IIfcModel
PIComposer APIPIComposer API

IIfcModel abstract#

abstract class IIfcModel extends IModel

Specialized interface for Industry Foundation Classes (IFC) model management extending the core IModel functionality with BIM-specific operations.

The IIfcModel interface provides comprehensive Building Information Modeling capabilities with the following specialized features:

Spatial Hierarchy Management:

  • Complete spatial structure handling (Project → Site → Building → Storey → Element)
  • Parent-child relationship management with automatic placement hierarchy
  • Spatial containment and aggregation relationships
  • Cross-model spatial structure copying and synchronization

Geometric Representation System:

  • Shape representation management (Body, Axis, Box, FootPrint, Reference)
  • Geometric context matching for inter-model operations
  • Mapped item creation for geometric reuse
  • Representation item composition with styling
  • Layer assignment and management

Property System Management:

  • Property set (PSet) association and disassociation
  • Type product relationships (IfcRelDefinesByType)
  • Material assignment and management
  • Comprehensive relationship clearing and maintenance

Relationship Handling:

  • Spatial relationships (IfcRelContainedInSpatialStructure, IfcRelAggregates)
  • Void and fill relationships (IfcRelVoidsElement, IfcRelFillsElement)
  • Property definition relationships (IfcRelDefinesByProperties)
  • Material association relationships (IfcRelAssociatesMaterial)
  • Type definition relationships (IfcRelDefinesByType)

Advanced BIM Operations:

  • Geometric context compatibility checking
  • Placement hierarchy traversal and manipulation
  • Cross-model element copying with dependency resolution
  • Type-based filtering for selective operations
  • Reference type management for project-wide declarations

Data Integrity & Persistence:

  • Automatic inverse relationship management
  • Cascade deletion with proper cleanup
  • Database persistence for all structural changes
  • Context-aware geometric operations
  • Unit consistency validation

This interface serves as the foundation for BIM applications requiring full IFC schema compliance, including architectural design, construction management, facility management, and interoperability with other BIM software platforms through standardized IFC exchange formats.

Implementations provide complete support for IFC2x3, IFC4, and other IFC schema versions with proper handling of spatial hierarchies, geometric representations, and property systems as defined by buildingSMART International standards.

Inheritance

Object → IObjectFactoryIModelIIfcModel

Available Extensions

Constructors#

IIfcModel()#

IIfcModel()

Properties#

createdAt no setter inherited#

int get createdAt

get creation time stamp

Inherited from IModel.

Implementation
//int getTimeStamp();
int get createdAt;

hashCode no setter inherited#

int get hashCode

The hash code for this object.

A hash code is a single integer which represents the state of the object that affects operator == comparisons.

All objects have hash codes. The default hash code implemented by Object represents only the identity of the object, the same way as the default operator == implementation only considers objects equal if they are identical (see identityHashCode).

If operator == is overridden to use the object state instead, the hash code must also be changed to represent that state, otherwise the object cannot be used in hash based data structures like the default Set and Map implementations.

Hash codes must be the same for objects that are equal to each other according to operator ==. The hash code of an object should only change if the object changes in a way that affects equality. There are no further requirements for the hash codes. They need not be consistent between executions of the same program and there are no distribution guarantees.

Objects that are not equal are allowed to have the same hash code. It is even technically allowed that all instances have the same hash code, but if clashes happen too often, it may reduce the efficiency of hash-based data structures like HashSet or HashMap.

If a subclass overrides hashCode, it should override the operator == operator as well to maintain consistency.

Inherited from Object.

Implementation
external int get hashCode;

id no setter inherited#

String get id

Gets the unique identifier of this model.

Inherited from IModel.

Implementation
//String getId();
String get id;

isIfc extension no setter#

bool get isIfc

Returns true if the model is a IFC model, false otherwise.

Available on IModel, provided by the IModelExtension extension

Implementation
bool get isIfc => isIfcSchema(schemaEnum);

isReference no setter inherited#

bool get isReference

Returns true if this is a reference model (read-only)

Inherited from IModel.

Implementation
bool get isReference;

name no setter inherited#

String get name

Gets the human-readable name of this model.

Inherited from IModel.

Implementation
// String getName();
String get name;

projectId no setter inherited#

String get projectId

Gets the project ID that this model belongs to.

Inherited from IModel.

Implementation
//String getProjectId();
String get projectId;

runtimeType no setter inherited#

Type get runtimeType

A representation of the runtime type of the object.

Inherited from Object.

Implementation
external Type get runtimeType;

schema no setter inherited#

ISchema get schema

Gets the schema definition used by this model.

Inherited from IModel.

Implementation
//ISchema getSchema();
ISchema get schema;

schemaEnum no setter inherited#

SupportedSchema get schemaEnum

Gets the schema enumeration value for this model.

Inherited from IModel.

Implementation
SupportedSchema get schemaEnum;

Methods#

addChild()#

bool addChild(IInstance parent, IInstance child, { String relType = ''})

Adds a child to a parent in the spatial hierarchy.

This method:

  1. Creates the appropriate relation type, which includes: a) IfcRelContainedInSpatialStructure b) IfcRelAggregates c) IfcRelVoidsElement d) IfcRelFillsElement and reuses existing relations when appropriate.
  2. Creates and manages the parallel object placement hierarchy by: - Creating IfcLocalPlacement for parent (except for IfcProject) and child
  • Setting the child's placement as a relative placement to the parent's placement
  • The child placement's resulting transformation matrix is initialized as the identity matrix and must be updated afterward if a specific transformation is required.
  1. Manages the inverse relations.

If relType is specified, it creates a relation of that type. relType must be a subtype of IfcRelation.

This function persists changes to both parent and child instances to the database.

Example:

// Assuming [createIfcProject] extension method has been called
final proj = getIfcProject();
final site = createInstance(typeName: 'IfcSite');

// Set some attributes
site.setAttributeByJson({
  "name": "my site",
  "RefElevation": 200,
});

final success = project.addChild(proj, site);
if (success) {
  // Translate site placement after adding to hierarchy
  final path = [
    'ObjectPlacement',
    'RelativePlacement',
    'IfcAxis2Placement3D',
    'Location',
    'Coordinates',
    0
  ];
  // Move the site 9 meters in the x-direction (9000mm in IFC units)
  final placement = site.setAttributeByPath(path, 9000.0);
  saveInstance(placement);
}

Changes made to parent and child are persisted to database.

Implementation
bool addChild(IInstance parent, IInstance child, {String relType = ''});

addInstanceRef() extension#

IInstance addInstanceRef( IInstance instance, IInstance ref, { String? attName, int? attIndex, bool addInverse = false, });

add instance reference and clean up the old reference. and return the old referenced instance

Available on IModel, provided by the IModelExtension extension

Implementation
IInstance addInstanceRef(IInstance instance, IInstance ref,
    {String? attName, int? attIndex, bool addInverse = false}) {
  if (instance.isNull || ref.isNull) {
    return createNullInstance();
  }

  final prevRef = instance.getInstance(attIndex: attIndex, attName: attName);
  IInstance prev = createNullInstance();
  if (!prevRef.isNull && prevRef.isInstanceReference) {
    prev = getInstance(prevRef.instanceHandle);
  }
  if (!prev.isNull) {
    prev.removeInverse(instance.instanceId);
  }
  instance.addInstanceRef(ref,
      attName: attName, attIndex: attIndex, addInverse: addInverse);
  return prev;
}

addMaterial()#

bool addMaterial(IInstance instance, IInstance material)

Adds an IfcRelAssociatesMaterial association to an instance.

This method associates the specified material relationship material with the given instance, establishing a material definition association.

Returns true if the material association was successfully created, or false if:

  • Either instance handle is invalid
  • The association already exists
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final materialRel = instanceFromJson({
  '@type': 'IfcRelAssociatesMaterial',
  'RelatingMaterial': {
    // IfcMaterialSelect selected type
    'IfcMaterial': {
      'Name': 'Concrete',
      'Category': 'Structural'
    }
  }
});
final success = addMaterial(wallInstance, materialRel);
if (success) {
  print('Material association added successfully');
} else {
  print('Failed to add material association');
}
Implementation
bool addMaterial(IInstance instance, IInstance material);

addPSet()#

bool addPSet(IInstance instance, IInstance relDef)

Adds an IfcRelDefinesByProperties association to an instance.

This method associates the specified property set relationship relDef with the given instance, establishing a property definition association.

Returns true if the property set association was successfully created, or false if:

  • Either instance handle is invalid
  • The association already exists
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final psetRel = instanceFromJson({
  '@type': 'IfcRelDefinesByProperties',
  // Select attribute, so in JSON, it is an object with
  // selected type as its attribute.
  'RelatingPropertyDefinition': {
    'IfcPropertySet': {
      'Name': 'Pset_WallCommon',
      'HasProperties': [
        {
          '@type': 'IfcPropertySingleValue',
          'Name': 'Reference',
          'NominalValue': {
            // IfcValue selected type
            'IfcSimpleValue': {
              // IfcSimpleValue selected type and value
              'IfcIdentifier': 'outer_wall.0'
            }
          }
        },
        {
          '@type': 'IfcPropertySingleValue',
          'Name': 'LoadBearing',
          'NominalValue': {
            // IfcValue selected type
            'IfcSimpleValue': {
              // IfcSimpleValue selected type and value
              'IfcBoolean': true
            }
          }
        },
        // ... additional properties
      ]
    }
  }
});
final success = addPSet(wallInstance, psetRel);
if (success) {
  print('Property set association added successfully');
} else {
  print('Failed to add property set association');
}
Implementation
bool addPSet(IInstance instance, IInstance relDef);

addRepItemToShape()#

IInstance addRepItemToShape( IInstance shape, IInstance repItem, IInstance styledItem, );

Adds an IfcRepresentationItem to a shape with an optional IfcStyledItem.

This method composes the repItem and styledItem within the shape and adds them to the shape's composite list of representation items. The styled item provides visual styling information for the representation item.

This function will fail if repItem is null.

Returns the updated shape instance with the new representation item added, or null instance if the operation fails.

Example usage:

final shape = createInstance(typeName: 'IfcShapeRepresentation');
final repItem = instanceFromJson({
  '@type': 'IfcExtrudedAreaSolid',
  'SweptArea': {
    '@type': 'IfcRectangleProfileDef',
    'ProfileType': 'AREA',
    'XDim': 100.0,
    'YDim': 9000.0
  },
  'ExtrudedDirection': {
    'DirectionRatios': [0.0, 0.0, 1.0]
  },
  'Depth': 1500.0
});
final styledItem = instanceFromJson({
  '@type': 'IfcStyledItem',
  'Styles': [
    {
      '@type': 'IfcSurfaceStyle',
      'Side': 'POSITIVE',
      'Styles': [
        // IfcSurfaceStyleElementSelect
        {
          // IfcSurfaceStyleElementSelect selected type
          'IfcSurfaceStyleRendering': {
            // IfcColourRgb instance skipping @type since it is final
            'SurfaceColour': {
              'Red': 1.0,
              'Green': 1.0,
              'Blue': 1.0
            },
            'Transparency': 0.0
          }
        }
      ]
    }
  ]
});

final updatedShape = addRepItemToShape(shape, repItem, styledItem);
if (!updatedShape.isNull) {
  print('Representation item added successfully to shape');
} else {
  print('Failed to add representation item to shape');
}
Implementation
IInstance addRepItemToShape(
  IInstance shape,
  IInstance repItem,
  IInstance styledItem,
);

addShape()#

IInstance addShape(IInstance instance, IInstance shape)

Adds a shape representation to an instance.

Instances can have multiple shape representations (e.g., body geometry, bounding box, 2D footprint, etc.). This method associates the specified shape with the given instance.

If the shape is already referenced by other product instances, this method creates and returns a new IfcMappedItem that references the original shape instead of directly reusing it. This ensures proper sharing of geometric definitions while maintaining instance-specific transformations.

Returns the added shape representation (either the original shape or a new IfcMappedItem referencing it), or null instance if the operation fails.

Example usage:

final wallInstance = createInstance(typeName: 'IfcWall');
// create a new shape
final bodyShape = instanceFromJson({
  '@type': 'IfcShapeRepresentation',
  'RepresentationIdentifier': 'Body',
  'RepresentationType': 'SweptSolid',
  'Items': [
    {
      '@type': 'IfcExtrudedAreaSolid',
      'SweptArea': {
        '@type': 'IfcRectangleProfileDef',
        'ProfileType': 'AREA',
        'XDim': 100.0,
        'YDim': 9000.0
      },
      'ExtrudedDirection': {
        'DirectionRatios': [0.0, 0.0, 1.0]
      },
      'Depth': 1500.0
    }
  ]
});

final addedShape = addShape(wallInstance, bodyShape);
if (!addedShape.isNull) {
  print('Shape successfully added to wall instance');
} else {
  print('Failed to add shape to wall instance');
}
Implementation
IInstance addShape(IInstance instance, IInstance shape);

addShapeAsMappedItemToShape()#

IInstance addShapeAsMappedItemToShape( IInstance shape, IInstance otherShape, IInstance style, );

Adds a shape otherShape as an IfcMappedItem to another shape instance.

This method converts the otherShape into an IfcMappedItem and adds it to the representation items of the target shape. The resulting mapped item will be styled with the provided style if it is not a null instance.

Returns the created IfcMappedItem instance, or null instance if the operation fails.

Example usage:

final wallShape = getShapes(wallInstance.instanceHandle).first;
final otheShape = getShapes(wallInstance1.instanceHandle).first;
final style = instanceFromJson({
  '@type': 'IfcStyledItem',
  'Styles': [
    {
      '@type': 'IfcSurfaceStyle',
      'Side': 'POSITIVE',
      'Styles': [
        // IfcSurfaceStyleElementSelect
        {
          // IfcSurfaceStyleElementSelect selected type
          'IfcSurfaceStyleRendering': {
            // IfcColourRgb instance skipping @type since it is final
            'SurfaceColour': {
              'Red': 1.0,
              'Green': 1.0,
              'Blue': 1.0
            },
            'Transparency': 0.0
          }
        }
      ]
    }
  ]
});

final mappedItem = addShapeAsMappedItemToShape(
  wallShape,
  otheShape,
  style,
);

if (!mappedItem.isNull) {
  print('shape successfully added as mapped item to wall shape');
  // The wall shape now contains the otheShape as a mapped representation
} else {
  print('Failed to add shape as mapped item to wall shape');
}
Implementation
IInstance addShapeAsMappedItemToShape(
  IInstance shape,
  IInstance otherShape,
  IInstance style,
);

addToLayer()#

bool addToLayer(IInstance shape, IInstance layer)

Adds an IfcShapeRepresentation instance to a layer (IfcPresentationLayerAssignment or IfcPresentationLayerWithStyle).

This method associates the specified shape representation shape with the given presentation layer layer. The layer can be either an IfcPresentationLayerAssignment or IfcPresentationLayerWithStyle instance.

Returns true if the shape was successfully added to the layer, or false if:

  • Either instance handle is invalid
  • The shape is already assigned to the layer
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final wallShape = getShapes(wallInstance.instanceHandle).first;
final structuralLayer = instanceFromJson({
  '@type': 'IfcPresentationLayerAssignment',
  'Name': 'structural layer',
  'Description': 'layer for load bearing structural elements'
});

final success = addToLayer(wallShape, structuralLayer);
if (success) {
  print('Wall shape successfully added to Structural layer');
} else {
  print('Failed to add wall shape to Structural layer');
}
Implementation
bool addToLayer(IInstance shape, IInstance layer);

addTypeProduct()#

bool addTypeProduct(IInstance instance, IInstance typeProd)

Associates an instance to an IfcRelDefinesByType relationship.

Returns true if the type product association was successfully created, or false if:

  • Either instance handle is invalid
  • The association already exists
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final wallType = instanceFromJson({
  '@type': 'IfcRelDefinesByType',
  'RelatingType': {
    '@type': 'IfcWallType',
    'Name': "a wall type",
    'PredefinedType': 'RETAININGWALL'
  }
});
final success = addTypeProduct(wallInstance, wallType);
if (success) {
  print('Type product associated successfully');
} else {
  print('Failed to associate type product');
}
Implementation
bool addTypeProduct(IInstance instance, IInstance typeProd);

axis2Placement3dFromMatrix() extension#

IInstance axis2Placement3dFromMatrix(Matrix4 mat)

Creates an Axis2Placement3D from a transformation matrix.

Extracts the location, axis, and reference direction from the matrix columns:

  • Location: column 3 (translation component)
  • Axis: column 2 (Z-axis direction)
  • Reference direction: column 0 (X-axis direction)

Available on IModel, provided by the IModelExtension extension

Implementation
IInstance axis2Placement3dFromMatrix(Matrix4 mat) {
  final location = mat.getColumn(3);
  final ref = mat.getColumn(0);
  final axis = mat.getColumn(2);
  return createAxis2Placement3D(
    [location[0], location[1], location[2]],
    [axis[0], axis[1], axis[2]],
    [ref[0], ref[1], ref[2]],
  );
}

canDelete() inherited#

bool canDelete(IInstance instance)

Checks if an instance can be safely deleted from the model.

This method performs a dependency analysis to determine if the instance can be deleted without causing referential integrity issues. It checks if any other instances in the model reference the specified instance.

Returns false if the instance is referenced by other instances, indicating that deletion would break relationships and cause database integrity problems.

Returns true otherwise

Inherited from IModel.

Implementation
bool canDelete(IInstance instance);

clear() inherited#

bool clear()

Clears all instances from the model. This completely empties the model database.

This method performs a complete wipe of all instances and associated data from the model, effectively resetting it to an empty state.

Returns true if the clear operation was successful, false otherwise.

Inherited from IModel.

Implementation
bool clear();

clearLayers()#

bool clearLayers(IInstance instance)

Clears all layer assignments from an instance.

This method removes all presentation layer associations (IfcPresentationLayerAssignment and IfcPresentationLayerWithStyle) from the specified instance. The instance will no longer be associated with any layers after this operation.

Returns true if all layer associations were successfully removed, or false if:

  • The instance handle is invalid
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final wallShape = getShapes(wallInstance.instanceHandle).first;
final success = clearLayers(wallShape);

if (success) {
  print('All layer assignments cleared successfully');
  // The shape is now not associated with any layers
  final remainingLayers = getLayers(wallShape.instanceHandle);
  print('Remaining layer associations: ${remainingLayers.length}');
} else {
  print('Failed to clear layer assignments');
}
Implementation
bool clearLayers(IInstance instance);

clearMaterials()#

bool clearMaterials(IInstance instance)

Clears all material assignments from an instance.

This method disassociates all IfcRelAssociatesMaterial relationships from the specified instance. If any of these relationships no longer reference any products after removal, they will be deleted from the database to maintain data integrity.

Returns true if all material associations were successfully removed, or false if:

  • The instance handle is invalid
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final success = clearMaterials(wallInstance);
if (success) {
  print('All material associations removed successfully');
  // Instance now has no material associations
} else {
  print('Failed to remove material associations');
}
Implementation
bool clearMaterials(IInstance instance);

clearPSets()#

bool clearPSets(IInstance instance)

Removes all property sets from an instance.

This method disassociates all IfcRelDefinesByProperties relationships from the specified instance. If any of these relationships no longer reference any products after removal, they will be deleted from the database to maintain data integrity.

Returns true if all property sets were successfully removed, or false if:

  • The instance handle is invalid
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final success = clearPSets(wallInstance);
if (success) {
  print('All property sets removed successfully');
  // Instance now has no property set associations
} else {
  print('Failed to remove property sets');
}
Implementation
bool clearPSets(IInstance instance);

clearRelations()#

bool clearRelations(IInstance instance)

Clears relations such as IfcRelDefinesByProperties, IfcRelDefinesByType, and IfcRelAssociatesMaterial from an instance.

This method disassociates all relationship entities including property sets, type definitions, and material associations from the specified instance. If any of these relationships no longer reference any products after removal, they will be deleted from the database to maintain data integrity.

Returns true if all relationships were successfully removed, or false if:

  • The instance handle is invalid
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final success = clearRelations(wallInstance);
if (success) {
  print('All relationships removed successfully');
  // Instance now has no property sets, type associations, or material assignments
} else {
  print('Failed to remove relationships');
}
Implementation
bool clearRelations(IInstance instance);

clearShapes()#

bool clearShapes(IInstance instance)

Removes all shape representations from the specified instance.

This method completely clears the IfcProductRepresentation's Representations values in the "Representation" attribute.

If a shape is composed by this instance, it will be deleted. If a referenced shape is no longer being used (referenced by other IfcProduct instances), it will be removed from the model.

This operation automatically persists changes to the instance in the database. No additional call to saveInstance is required for the shape removal.

Returns true if all shapes were successfully removed, or false if:

  • The instance handle is invalid

Use this method with caution as it permanently removes all geometric data. Consider using removeShape for selective removal if needed.

Example usage:

// Remove all geometry from a temporary or placeholder instance
final success = clearShapes(templateInstance);
if (success) {
  print('All shapes cleared successfully - changes saved automatically');
  // Now ready to add new geometry or repurpose the instance
} else {
  print('Failed to clear shapes - instance may be invalid');
}
Implementation
bool clearShapes(IInstance instance);

convertShapeToMappedRepresentation()#

IInstance convertShapeToMappedRepresentation( IInstance shape, IInstance prod, [ double scale = 1.0, ]);

Converts a shape to a mapped representation for sharing with another product.

This method transforms a shape representation into an IfcMappedItem, allowing it to be shared and reused across multiple product instances. The transformation includes optional scaling through an IfcCartesianTransformationOperator3D.

The prod parameter may be a null instance if the mapped representation should not be associated with a specific product. The scale parameter applies scaling to the IfcCartesianTransformationOperator3D transformation.

Returns the created IfcMappedItem instance, or null instance if the operation fails.

Example usage:

final wallShape = getShapes(wallInstance.instanceHandle).first;
final mappedRepresentation = convertShapeToMappedRepresentation(
  wallShape,
  wallInstance,
  1.0, // scale factor
);

if (!mappedRepresentation.isNull) {
  print('Shape successfully converted to mapped representation');
  // The mapped representation can now be shared with other products
} else {
  print('Failed to convert shape to mapped representation');
}
Implementation
IInstance convertShapeToMappedRepresentation(
  IInstance shape,
  IInstance prod, [
  double scale = 1.0,
]);

copyChildrenOfTypesWithComposedDependency()#

List<IInstance> copyChildrenOfTypesWithComposedDependency( IModel fromModel, IInstance fromInstance, IInstance toInstance, List<String> types, { List<String> includeRelTypes = const[], });

Copies children of specific types from fromInstance to toInstance, potentially across models.

This method copies children from the source instance fromInstance in the fromModel to the target instance toInstance in the current model. The types parameter specifies which IFC types to copy - if the list is empty, all children will be copied.

For each child instance, the placement hierarchy and spatial structure are copied, but property sets (PSets), materials, and other non-spatial associations are not included.

The operation can work both within the same model (set fromModel to null) or across different IFC models. When copying across models, the caller must ensure that both models have compatible geometric contexts and units.

Returns a list of all copied and updated instances in the current model. You must call saveInstances to persist these changes to the database.

Important: The caller is responsible for ensuring context compatibility between fromModel and this model, particularly for geometric representations.

Note: This method copies placement hierarchy, spatial relationships, and Optionally, propertysets, materials and typeproducts as specified by relTypeIds type list current support relTypes: IfcRelAssociatesMaterial, IfcRelDefinesByProperties, IfcRelDefinesByType

Example usage:

// Copy only walls and slabs from a building storey
final sourceStorey = getInstance(storeyHandle);
final targetStorey = getInstance(targetStoreyHandle);
final typesToCopy = [toTypeId('IfcWall'), toTypeId('IfcSlab')];

final copiedInstances = copyChildrenOfTypesWithComposedDependency(
  null, // same model
  sourceStorey,
  targetStorey,
  typesToCopy,
);

if (copiedInstances.isNotEmpty) {
  saveInstances(copiedInstances);
  print('Successfully copied ${copiedInstances.length} filtered children');
} else {
  print('No children of specified types were found');
}

// Copy all children (empty types list)
final allChildren = copyChildrenOfTypesWithComposedDependency(
  null,
  sourceStorey,
  targetStorey,
  [], // empty list copies all children
);
Implementation
List<IInstance> copyChildrenOfTypesWithComposedDependency(IModel fromModel,
    IInstance fromInstance, IInstance toInstance, List<String> types,
    {List<String> includeRelTypes = const []});

copyChildrenWithComposedDependency()#

List<IInstance> copyChildrenWithComposedDependency( IModel fromModel, IInstance fromInstance, IInstance toInstance, List<IInstance> children, { List<String> includeRelTypes = const[], });

Copies spatial children from fromInstance to toInstance, potentially across models.

This method copies the specified children from the source instance fromInstance in the fromModel to the target instance toInstance in the current model. For each child instance, the placement hierarchy and spatial structure are copied, but property sets (PSets), materials, and other non-spatial associations are not included.

The operation can work both within the same model (set fromModel to null) or across different IFC models. When copying across models, the caller must ensure that both models have compatible geometric contexts and units.

Returns a list of all copied and updated instances in the current model.

Important: The caller is responsible for ensuring context compatibility between fromModel and this model, particularly for geometric representations.

Note: This method copies placement hierarchy, spatial relationships, and Optionally, propertysets, materials and typeproducts as specified by relTypeIds type list current support relTypes: IfcRelAssociatesMaterial, IfcRelDefinesByProperties, IfcRelDefinesByType

Example usage:

// Copy children within the same model (placement hierarchy only)
final sourceStorey = getInstance(sourceStoreyHandle);
final targetStorey = getInstance(targetStoreyHandle);
final storeyChildren = getSpatialChildren(sourceStorey.instanceHandle);

final copiedInstances = copyChildrenWithComposedDependency(
  null, // same model
  sourceBuilding,
  targetBuilding,
  storeyChildren,
  ['IfcRelDefinesByProperties']
);

if (copiedInstances.isNotEmpty) {
  saveInstances(copiedInstances);
  print('Successfully copied ${copiedInstances.length} children with placement hierarchy');
  // Note: Property sets and materials need to be copied separately if needed
} else {
  print('No children were copied');
}
Implementation
List<IInstance> copyChildrenWithComposedDependency(IModel fromModel,
    IInstance fromInstance, IInstance toInstance, List<IInstance> children,
    {List<String> includeRelTypes = const []});

copyInstance() inherited#

IInstance copyInstance(IModel fromModel, IInstance instance)

Copies an instance from another model into this model.

This method creates a copy of the specified instance from the fromModel and adds it to the current model. If fromModel is null, the copy is performed within the same model.

The copy operation performs the following transformations:

  • Nullifies references: All entity reference attributes in the copied instance are set to null to avoid cross-model reference issues
  • Removes inverse relations: Any inverse relationship attributes are cleared to maintain referential integrity
  • Resolves IDs: The copied instance receives a new consistent instance ID that fits within this model's ID allocation scheme
  • if instance is a IfcRoot instance (ifc model), it is assigned a new IfcGloballyUniqueId

This method is ideal for copying simple instances without complex dependency hierarchies. For copying instances with composed dependencies, use copyInstanceWithComposedDependency instead.

Parameters:

  • fromModel: The source model containing the instance to copy. If null, the copy is performed within the current model.
  • instance: The instance to copy from the source model.

Returns the copied IInstance in the current model, or null instance copy fails

Example usage:

// Copy a point from another model
final otherModel = getOtherModel();
final pt = otherModel.getInstancesByType(toTypeId('cartesian_point')).first;

final copiedPt = copyInstance(otherModel, pt);
if (!copiedPt.isNull) {
  print('copiedPt copied successfully with new ID: ${copiedPt.instanceId}');
} else {
  print('Failed to copy pt');
}

See also:

Inherited from IModel.

Implementation
IInstance copyInstance(IModel fromModel, IInstance instance);

copyInstanceWithComposedDependency() inherited#

List<IInstance> copyInstanceWithComposedDependency( IModel fromModel, IInstance instance, );

Copies an instance along with its composed dependency hierarchy from another model.

This method performs a deep copy of the specified instance from the fromModel, including all its composed child instances and non-reference type dependencies. Unlike copyInstance, this method preserves the complete composition hierarchy by recursively copying dependent instances that are composed within the main instance.

The copy operation handles different attribute types differently:

  • Reference types: Attributes marked as reference types (via isReferenceType) are not copied and remain as null references in the copied instance
  • Non-reference types: Composed child instances and non-reference attributes are recursively copied to maintain the complete dependency hierarchy
  • Inverses: Inverses are cleared

Parameters:

  • fromModel: The source model containing the instance and its dependencies to copy. Must not be null for cross-model copying.
  • instance: The root instance to copy from the source model, along with its composed dependency hierarchy.

Returns a list of IInstance objects where:

  • The first element is the copy of the root instance

Returns an empty list if failed.

Example usage:

// Copy a wall with all its composed properties and geometry
final otherModel = getOtherModel();
final wallToCopy = otherModel.getInstancesByType(toTypeId('IfcWall')).first;

final copied = copyInstanceWithComposedDependency(otherModel, wallToCopy);
if (copied.isNotEmpty) {
  final copiedWall = copied[0];
  print('New wall ID: ${copiedWall.instanceId}');
  // Composition hierarchy is preserved, reference types are nullified
} else {
  print('Failed to copy wall with dependencies');
}

⚠️ Important Considerations:

  • Reference type attributes will be nullified in the copied hierarchy
  • All copied instances receive new consistent IDs in the target model

See also:

Inherited from IModel.

Implementation
List<IInstance> copyInstanceWithComposedDependency(
    IModel fromModel, IInstance instance);

copyRelationOfTypesWithComposedDependency()#

List<IInstance> copyRelationOfTypesWithComposedDependency( IModel fromModel, IInstance fromInstance, IInstance toInstance, List<String> relTypeNames, );

copy related properties from fromInstance to toInstance current support relTypes: IfcRelAssociatesMaterial, IfcRelDefinesByProperties, IfcRelDefinesByType

Implementation
List<IInstance> copyRelationOfTypesWithComposedDependency(IModel fromModel,
    IInstance fromInstance, IInstance toInstance, List<String> relTypeNames);

createAxis2Placement2D() extension#

IInstance createAxis2Placement2D(List<double> location, [ List<double>? ref])

Creates an Axis2Placement2D from location and reference direction.

The location parameter must contain 2 coordinates. The ref parameter is optional but must contain 2 coordinates if provided. Returns a null instance if any coordinate list has an invalid length.

Available on IModel, provided by the IModelExtension extension

Implementation
IInstance createAxis2Placement2D(List<double> location, [List<double>? ref]) {
  if (location.length != 2) {
    return createNullInstance();
  }
  final placement = createInstance(
      typeName: isIfc ? kIfcAxis2Placement2d : kAxis2Placement2d)
    ..setAttribute(createCartesianPoint(location), attName: 'location');
  ref ??= [1.0, 0];
  if (ref.length != 2) {
    return createNullInstance();
  }
  final refDir = createDirection(ref);
  placement.setAttribute(refDir,
      attName: isIfc ? 'refdirection' : 'ref_direction');
  return placement;
}

createAxis2Placement3D() extension#

IInstance createAxis2Placement3D( List<double> location, [ List<double>? axis, List<double>? ref, ]);

Creates an Axis2Placement3D from location, axis, and reference direction.

The location parameter must contain 3 coordinates. The axis and ref parameters are optional but must contain 3 coordinates if provided. Returns a null instance if any coordinate list has an invalid length.

Available on IModel, provided by the IModelExtension extension

Implementation
IInstance createAxis2Placement3D(List<double> location,
    [List<double>? axis, List<double>? ref]) {
  if (location.length != 3) {
    return createNullInstance();
  }
  final placement = createInstance(
      typeName: isIfc ? kIfcAxis2Placement3d : kAxis2Placement3d)
    ..setAttribute(createCartesianPoint(location), attName: 'location');
  axis ??= [0, 0, 1.0];
  if (axis.length != 3) {
    return createNullInstance();
  }
  placement.setAttribute(createDirection(axis), attName: 'axis');
  ref ??= [1.0, 0, 0];
  if (ref.length != 3) {
    return createNullInstance();
  }
  placement.setAttribute(createDirection(ref),
      attName: isIfc ? 'RefDirection' : 'ref_direction');
  return placement;
}

createCartesianPoint() extension#

IInstance createCartesianPoint(List<double> coords)

Creates a Cartesian point from coordinates.

The coordinates list must contain either 2 or 3 values for 2D or 3D points respectively. Returns a null instance if the coordinate list length is invalid.

Available on IModel, provided by the IModelExtension extension

Implementation
IInstance createCartesianPoint(List<double> coords) {
  final length = coords.length;
  if (length != 2 && length != 3) {
    return createNullInstance();
  }
  final inst =
      createInstance(typeName: isIfc ? kIfcCartesianPoint : kCartesianPoint)
        ..setAttribute(coords, attName: 'coordinates');
  return inst;
}

createDirection() extension#

IInstance createDirection(List<double> coords)

Creates a direction vector from direction ratios.

The direction ratios list must contain either 2 or 3 values for 2D or 3D directions respectively. Returns a null instance if the ratios list length is invalid.

Available on IModel, provided by the IModelExtension extension

Implementation
IInstance createDirection(List<double> coords) {
  final length = coords.length;
  if (length != 2 && length != 3) {
    return createNullInstance();
  }
  return createInstance(typeName: isIfc ? kIfcDirection : kDirection)
    ..setAttribute(coords,
        attName: isIfc ? 'DirectionRatios' : 'direction_ratios');
}

createEnum() inherited#

PIEnum createEnum({ int? typeId, String? typeName, int? value, String? stringValue, });

Creates an EXPRESS enumeration instance.

typeId: Hash-based type identifier of the enumeration typeName: EXPRESS type name of the enumeration value: Integer value to initialize the enumeration stringValue: String representation value to initialize the enumeration

Returns null enum if typeId or typeName does not correspond to a valid EXPRESS enumeration type.

Inherited from IObjectFactory.

Implementation
PIEnum createEnum(
    {int? typeId, String? typeName, int? value, String? stringValue});

createHeader() extension#

IInstance createHeader(PIModelHeader header)

Creates the header instance from PIModelHeader structure. The header instance captures all information in the header section of the Part 21 CSV file: HEADER; header information. ENDSEC; The header instance has three instance attributes:

  1. file_description
  2. file_name
  3. file_schema

Available on IModel, provided by the IModelExtension extension

Implementation
IInstance createHeader(PIModelHeader header) {
  final fileDescription =
      createInstance(typeName: 'file_description', setId: false)
        ..setAttribute(header.description, attName: 'description')
        ..setAttribute(
            header.implementation_level.isEmpty
                ? kImplementationLevel
                : header.implementation_level,
            attName: 'implementation_level');
  final fileName = createInstance(typeName: 'file_name', setId: false)
    ..setAttribute(header.name, attName: 'name')
    ..setAttribute(PIModelHeader.getTimeStamp(), attName: 'time_stamp')
    ..setAttribute(header.author.isEmpty ? [kAuthor] : header.author,
        attName: 'author')
    ..setAttribute(header.organization, attName: 'organization')
    ..setAttribute(
        header.preprocessor_version.isEmpty
            ? kProcessorVersion
            : header.preprocessor_version,
        attName: 'preprocessor_version')
    ..setAttribute(header.originating_system, attName: 'originating_system')
    ..setAttribute(header.authorization, attName: 'authorization');
  final schemas = [header.schema_identifier.toUpperCase()];
  final fileSchema = createInstance(typeName: 'file_schema', setId: false)
    ..setAttribute(schemas, attIndex: 0);
  final headerInst = createInstance(typeName: 'file_header', setId: false)
    ..setAttribute(fileDescription, attIndex: 0)
    ..setAttribute(fileName, attIndex: 1)
    ..setAttribute(fileSchema, attIndex: 2);
  headerInst.setAttribute(header.schemaEnum.index, attName: 'schema_enum');
  return headerInst;
}

createIfcProject() extension#

IInstance createIfcProject()

Creates an IFC Project instance including all context information. Uses header data for author and organization information.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createIfcProject() {
  final header = getHeader();
  final fileName = header.getInstance(attName: 'filename');
  final author = fileName.getStrings(attName: 'author');
  &#47;&#47; ifcpersion
  final person = createInstance(typeName: 'IFCPERSON');
  final familyName = author.isNotEmpty ? author.first : '';
  final givenName = author.length > 1 ? author[1] : '';
  if (familyName.isNotEmpty) {
    person.setAttribute(familyName, attName: 'FamilyName');
  }
  if (givenName.isNotEmpty) {
    person.setAttribute(givenName, attName: 'GivenName');
  }
  &#47;&#47; IFCORGANIZATION
  final headerOrg = fileName.getStrings(attName: 'organization');
  final orgName = headerOrg.isNotEmpty ? headerOrg.first : '';
  final organization = createInstance(typeName: 'IFCORGANIZATION')
    ..setAttribute(orgName, attName: 'Name');
  &#47;&#47; IFCAPPLICATION
  final app = createInstance(typeName: 'IFCAPPLICATION')
    ..setInstanceRef(organization, attIndex: 0)
    ..setAttribute('1.0', attIndex: 1)
    ..setAttribute('PIComposer', attIndex: 2)
    ..setAttribute('PIC', attIndex: 3);
  &#47;&#47; IFCPERSONANDORGANIZATION
  final personorg = createInstance(typeName: 'IFCPERSONANDORGANIZATION')
    ..setInstanceRef(person, attIndex: 0)
    ..setInstanceRef(organization, attIndex: 1);
  &#47;&#47; IFCOWNERHISTORY
  final stateEnum =
      createEnum(typeName: 'IfcStateEnum', stringValue: 'READWRITE');
  final seconds = DateTime.now().millisecondsSinceEpoch ~&#47; 1000;
  final ownerHist = createInstance(typeName: 'IFCOWNERHISTORY')
    ..setInstanceRef(personorg, attIndex: 0)
    ..setInstanceRef(app, attIndex: 1)
    ..setAttribute(stateEnum, attIndex: 2)
    ..setAttribute(seconds, attIndex: 7);
  &#47;&#47; application context...
  final zero = [0.0, 0.0, 0.0];
  final ratioZ = [0.0, 0.0, 1.0];
  final ratiox = [1.0, 0.0, 0.0];
  final north = [0.0, 1.0];
  final contextaxispl3d = createAxis2Placement3D(zero, ratioZ, ratiox);
  final trueNorth = createInstance(typeName: 'IfcDirection');
  trueNorth.setAttribute(north, attName: 'DirectionRatios');
  &#47;&#47; IFCGEOMETRICREPRESENTATIONCONTEXT
  final geomcontext =
      createInstance(typeName: 'IFCGEOMETRICREPRESENTATIONCONTEXT')
        ..setAttribute('Model', attIndex: 1)
        ..setAttribute(3, attIndex: 2)
        ..setAttribute(1.0e-5, attIndex: 3);
  final wcSel = createSelect(typeId: Axis2PlacementId)
    ..setSelectedType(typeId: contextaxispl3d.typeId)
    ..setValue(contextaxispl3d);
  geomcontext.setAttribute(wcSel, attIndex: 4);
  geomcontext.setAttribute(attName: 'TrueNorth', trueNorth);
  &#47;&#47;IFCGEOMETRICREPRESENTATIONSUBCONTEXT
  final subcontext =
      createInstance(typeName: 'IFCGEOMETRICREPRESENTATIONSUBCONTEXT')
        ..setAttribute('Body', attIndex: 0)
        ..setAttribute('Model', attIndex: 1)
        ..setAttribute(attName: 'CoordinateSpaceDimension', 3)
        ..setInstanceRef(geomcontext, attIndex: 6);
  final subcontextFootPrint =
      createInstance(typeName: 'IFCGEOMETRICREPRESENTATIONSUBCONTEXT')
        ..setAttribute('FootPrint', attIndex: 0)
        ..setAttribute('Model', attIndex: 1)
        ..setAttribute(attName: 'CoordinateSpaceDimension', 2)
        ..setInstanceRef(geomcontext, attIndex: 6);
  final subcontextAxis =
      createInstance(typeName: 'IFCGEOMETRICREPRESENTATIONSUBCONTEXT')
        ..setAttribute('Axis', attIndex: 0)
        ..setAttribute('Model', attIndex: 1)
        ..setAttribute(attName: 'CoordinateSpaceDimension', 1)
        ..setInstanceRef(geomcontext, attIndex: 6);
  &#47;&#47; TargetView
  final targetView = createEnum(
      typeName: 'IfcGeometricProjectionEnum', stringValue: 'MODEL_VIEW');
  subcontext.setAttribute(targetView, attIndex: 8);
  subcontextFootPrint.setAttribute(targetView, attIndex: 8);
  subcontextAxis.setAttribute(targetView, attIndex: 8);
  final unitAssign = createModelUnits();
  &#47;&#47;IFCPROJECT
  final projName = fileName.getString(attIndex: 0).getOrElse(() => '');
  final proj = createInstance(typeId: ProjectId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0)
    ..setInstanceRef(ownerHist, attIndex: 1, addInverse: false)
    ..setAttribute(projName, attIndex: 2)
    ..addInstanceRef(geomcontext, attIndex: 7, addInverse: false)
    ..setInstanceRef(unitAssign, attIndex: 8, addInverse: false);
  saveInstances([
    person,
    organization,
    personorg,
    ownerHist,
    app,
    geomcontext,
    subcontext,
    subcontextAxis,
    subcontextFootPrint,
    unitAssign,
    proj,
  ]);
  return proj;
}

createInstance() inherited#

IInstance createInstance({ String? typeName, int? typeId, bool setId = true})

Creates an ENTITY instance of the specified type.

typeName: EXPRESS entity type name to create typeId: Hash-based type identifier to create setId: If true, automatically assigns a new instance identifier. Set to false for header instances or when manual ID assignment is needed.

Returns a new IInstance of the requested type.

Inherited from IObjectFactory.

Implementation
IInstance createInstance({String? typeName, int? typeId, bool setId = true});

createInstanceReference() inherited#

IInstance createInstanceReference(InstanceHandle instHandle)

Creates an instance reference from an instance handle.

instHandle: The InstanceHandle containing reference information

Returns a lightweight reference instance pointing to the specified target.

Inherited from IObjectFactory.

Implementation
IInstance createInstanceReference(InstanceHandle instHandle);

createModelUnits() extension#

IInstance createModelUnits()

Creates default IFCUNITASSIGNMENT for PIComposer IFC model. Length measure is in millimeters, other measures follow metric MKS system.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createModelUnits() {
  final unitAssignSelects = <ISelect>[];
  unitAssignSelects.add(_createLengthUnit());
  unitAssignSelects.add(_createAngleUnit());
  unitAssignSelects.add(_createAreaUnit());
  unitAssignSelects.add(_createVolumeUnit());
  unitAssignSelects.add(_createMassUnit());
  unitAssignSelects.add(_createTimeUnit());
  unitAssignSelects.add(_createSolidAngleUnit());
  unitAssignSelects.add(_createTemperatureUnit());
  unitAssignSelects.add(_createLumenUnit());
  return createInstance(typeName: 'IFCUNITASSIGNMENT')
    ..setAttribute(unitAssignSelects, attIndex: 0);
}

createNullInstance() inherited#

IInstance createNullInstance()

Creates a null instance representing an unset or missing value.

Returns a special IInstance that represents a null value.

Inherited from IObjectFactory.

Implementation
IInstance createNullInstance();

createPSetFromTemplate() extension#

IInstance createPSetFromTemplate(IBlocklyTemplate psetTemplate)

Creates an IfcPropertySet from an IBlocklyPropertySetTemplate.

psetTemplate provides the property set definition template. Returns a null instance if parsing fails or template is invalid.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createPSetFromTemplate(
  IBlocklyTemplate psetTemplate,
) {
  if (psetTemplate is! IBlocklyPropertySetTemplate) {
    return createNullInstance();
  }
  final dictionary = psetTemplate.getDictionary();
  final parser = PSetTemplateParser(dictionary, PSetTemplate());
  if (!parser.parse()) {
    return createNullInstance();
  }
  PSetTemplate template = parser.template;
  final pset = createInstance(typeId: PropertySetId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0)
    ..setAttribute(template.type, attIndex: 2);
  final ps = <IInstance>[];
  for (final p in template.properties) {
    try {
      final prop = _createProperty(p);
      ps.add(prop);
    } catch (e) {
      &#47;&#47; Skip property on error
    }
  }
  pset.setAttribute(ps, attIndex: 4);
  final ifcPropertySetDefinitionSelect =
      createSelect(typeName: 'IfcPropertySetDefinitionSelect')
        ..setSelectedType(typeName: 'IfcPropertySet')
        ..setValue(pset);
  final relDef = createInstance(typeId: RelDefinesByPropertiesId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0)
    ..setAttribute(ifcPropertySetDefinitionSelect, attIndex: 5);
  return relDef;
}

createPSetOfType() extension#

IInstance createPSetOfType(String psetName)

Creates a predefined IfcPropertySet with the given type name.

This method creates a standard IFC property set structure including:

  • An IfcPropertySet instance with a generated GUID
  • The specified psetName as the property set type identifier
  • A relational structure (IfcRelDefinesByProperties) that links the property set to potential elements

psetName should be a valid IFC property set type name (e.g., 'Pset_WallCommon', 'Pset_BeamCommon') either defined in the schema EXPRESS file or is defined via a template.

Returns an IInstance of IfcRelDefinesByProperties that can be associated with building elements to assign the property set.

Example:

final relPset = createPSetOfType('Pset_WallCommon');
final wall = createInstance(typeName: 'IfcWall');
relPset.addInstanceRef(wall, attName: 'RelatedObjects');

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createPSetOfType(String psetName) {
  final pset = createInstance(typeId: PropertySetId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0)
    ..setAttribute(psetName, attIndex: 2);
  final ifcPropertySetDefinitionSelect =
      createSelect(typeName: 'IfcPropertySetDefinitionSelect')
        ..setSelectedType(typeName: 'IfcPropertySet')
        ..setValue(pset);
  final relDef = createInstance(typeId: RelDefinesByPropertiesId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0)
    ..setAttribute(ifcPropertySetDefinitionSelect,
        attName: 'RelatingPropertyDefinition');
  return relDef;
}

createQSetFromTemplate() extension#

IInstance createQSetFromTemplate(IBlocklyTemplate qsetTemplate)

Creates an IfcQuantitySet from an IBlocklyQuantitySetTemplate.

qsetTemplate provides the quantity set definition template. Returns a null instance if parsing fails or template is invalid.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createQSetFromTemplate(
  IBlocklyTemplate qsetTemplate,
) {
  if (qsetTemplate is! IBlocklyQuantitySetTemplate) {
    return createNullInstance();
  }
  final dictionary = qsetTemplate.getDictionary();
  if (dictionary.isEmpty) {
    return createNullInstance();
  }
  final parser = QuantitySetParser(dictionary, QuantitySetTemplate());
  if (!parser.parse()) {
    return createNullInstance();
  }
  final template = parser.template;
  final qset = createInstance(typeId: ElementQuantityId);
  qset.setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0);
  qset.setAttribute(template.type, attIndex: 2);
  final qs = <IInstance>[];
  for (final q in template.quantitys) {
    try {
      final quant = _createQuantity(q);
      qs.add(quant);
    } catch (e) {
      &#47;&#47; Skip quantity on error
    }
  }
  qset.setAttribute(attName: 'Quantities', qs);
  final ifcPropertySetDefinitionSelect =
      createSelect(typeName: 'IfcPropertySetDefinitionSelect')
        ..setSelectedType(typeName: 'IfcPropertySet')
        ..setValue(qset);
  final relDef = createInstance(typeId: RelDefinesByPropertiesId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0)
    ..setAttribute(ifcPropertySetDefinitionSelect, attIndex: 5);
  return relDef;
}

createQSetOfType() extension#

IInstance createQSetOfType(String qsetName)

Creates a predefined IfcQuantitySet with the given type name.

This method creates a standard IFC quantity set structure including:

  • An IfcElementQuantity instance with a generated GUID
  • The specified qsetName as the quantity set type identifier
  • A relational structure (IfcRelDefinesByProperties) that links the quantity set to potential elements

qsetName should be a valid IFC quantity set type name (e.g., 'Qto_WallBaseQuantities', 'Qto_BeamBaseQuantities').

Returns an IInstance of IfcRelDefinesByProperties that can be associated with building elements to assign the quantity set.

Example:

final relPset = createQSetOfType('Qto_WallBaseQuantities');
final wall = createInstance(typeName: 'IfcWall');
relPset.addInstanceRef(wall, attName: 'RelatedObjects');

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createQSetOfType(String qsetName) {
  final pset = createInstance(typeId: ElementQuantityId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0)
    ..setAttribute(qsetName, attIndex: 2);
  final ifcPropertySetDefinitionSelect =
      createSelect(typeName: 'IfcPropertySetDefinitionSelect')
        ..setSelectedType(typeName: 'IfcPropertySet')
        ..setValue(pset);
  final relDef = createInstance(typeId: RelDefinesByPropertiesId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0)
    ..setAttribute(ifcPropertySetDefinitionSelect,
        attName: 'RelatingPropertyDefinition');
  return relDef;
}

createRelAggregate() extension#

IInstance createRelAggregate({ IInstance? parent, IInstance? child})

Creates an IfcRelAggregates relationship.

Optional parent and child parameters set the relationship endpoints.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createRelAggregate({IInstance? parent, IInstance? child}) {
  final relAg = createInstance(typeId: RelAggregatesId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0);
  if (null != parent) {
    relAg.setInstanceRef(parent, attIndex: 4);
  }
  if (null != child) {
    relAg.addInstanceRef(child, attIndex: 5, addInverse: false);
  }
  return relAg;
}

createRelContainSpatial() extension#

IInstance createRelContainSpatial({ IInstance? parent, IInstance? child})

Creates an IfcRelContainedInSpatialStructure relationship.

Optional parent and child parameters set the relationship endpoints.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createRelContainSpatial({IInstance? parent, IInstance? child}) {
  final relContain = createInstance(typeId: RelContainedInSpatialStructureId)
    ..setAttribute(PIComposerAPIFFI.getGuid(), attIndex: 0);
  if (null != parent) {
    relContain.setInstanceRef(parent, attIndex: 5);
  }
  if (null != child) {
    relContain.addInstanceRef(child, attIndex: 4, addInverse: false);
  }
  return relContain;
}

createSelect() inherited#

ISelect createSelect({ int? typeId, String? typeName, int? selectedType, String? selectedTypeName, });

Creates an EXPRESS SELECT instance.

typeId: Hash-based type identifier of the SELECT type typeName: EXPRESS type name of the SELECT type selectedType: Optional initial selected type identifier

Returns a configured ISelect instance ready for use.

Inherited from IObjectFactory.

Implementation
ISelect createSelect(
    {int? typeId,
    String? typeName,
    int? selectedType,
    String? selectedTypeName});

createStyledItem() extension#

IInstance createStyledItem(List<double> color)

Creates an IfcStyledItem from RGBA color values.

color must contain at least 3 values (RGBA), A default to 0.0. Returns a null instance if color data is insufficient.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance createStyledItem(List<double> color) {
  if (color.length < 3) {
    return createNullInstance();
  }
  final ifcColourRgb = createInstance(typeName: 'IFCCOLOURRGB')
    ..setAttribute(color[0], attIndex: 1)
    ..setAttribute(color[1], attIndex: 2)
    ..setAttribute(color[2], attIndex: 3);

  final reflectance = createEnum(
      typeName: 'IfcReflectanceMethodEnum', stringValue: 'NOTDEFINED');
  final ifcSurfaceStyleRendering =
      createInstance(typeName: 'IFCSURFACESTYLERENDERING')
        ..setAttribute(ifcColourRgb, attName: 'SurfaceColour')
        ..setAttribute(color.length == 4 ? color[3] : 0.0,
            attName: 'Transparency')
        ..setAttribute(reflectance, attName: 'ReflectanceMethod');

  final surfaceStyleElementSelect =
      createSelect(typeName: 'IFCSURFACESTYLEELEMENTSELECT')
        ..setSelectedType(typeId: ifcSurfaceStyleRendering.typeId)
        ..setValue(ifcSurfaceStyleRendering);

  final ifcSurfaceSideEnum =
      createEnum(typeName: 'IfcSurfaceSide', stringValue: 'POSITIVE');
  final styles = [surfaceStyleElementSelect];

  final ifcSurfaceStyle = createInstance(typeName: 'IFCSURFACESTYLE')
    ..setAttribute(ifcSurfaceSideEnum, attName: 'Side')
    ..setAttribute(styles, attName: 'Styles');
  final surfaceStyles = [ifcSurfaceStyle];
  return createInstance(typeName: 'IFCSTYLEDITEM')
    ..setAttribute(surfaceStyles, attName: 'Styles');
}

deleteChild()#

bool deleteChild(IInstance parent, IInstance instance)

Removes a child instance from its parent in the spatial hierarchy.

This method manages the complete object hierarchy removal by:

  1. Removing the child from the parent's spatial structure relations
  2. Removing the child's placement from the placement hierarchy
  3. Cleaning up inverse relationships between parent and child
  4. Performing cascade deletion of grandchildren and deeper descendants

The operation performs a cascade delete, meaning it will recursively remove all grandchildren and deeper descendants of the child instance being deleted.

The operation will fail if:

  • The instance has children with relationships that cannot be cascade deleted (unless the children relations are 1-1, such as IfcOpeningElement and IfcFillsElement relationships)
  • The parent-child relationship does not exist
  • The instances are invalid or not part of this model

For 1-1 relationships like opening elements and their fills, this method will handle the specific deletion rules appropriate for those relation types.

Use with caution as cascade delete will permanently remove all descendant instances from the model.

Changes made are persisted to database.

Implementation
bool deleteChild(IInstance parent, IInstance instance);

deleteInstance() inherited#

bool deleteInstance(IInstance instance)

Removes an instance from the model and database.

This method permanently deletes the instance specified by instance handle from both the database storage. For memory-only models, the instance is removed from the in-memory collection. For database-backed models, the instance is permanently deleted from storage.

It is strongly recommended to call canDelete before using this method to ensure the instance can be safely removed without causing referential integrity issues. If an instance is referenced by other instances, deletion may orphan those references and cause database consistency problems.

Returns true if the instance was successfully deleted, or false otherwise.

Inherited from IModel.

Implementation
bool deleteInstance(IInstance instance);

deleteTypeProduct()#

bool deleteTypeProduct(IInstance instance)

Removes the type product association from an instance.

This method disassociates the instance from its type product by removing the reference from the IfcRelDefinesByType relationship. If the IfcRelDefinesByType no longer references any product instances after this removal, both the relationship and the composed IfcTypeProduct will be deleted from the model to maintain data integrity.

Returns true if the type product association was successfully removed, or false if:

  • The instance handle is invalid
  • No type product association exists for this instance
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final success = deleteTypeProduct(wallInstance);
if (success) {
  print('Type product association removed successfully');
  // The wall instance is now independent of any type definition
} else {
  print('Failed to remove type product association');
}
Implementation
bool deleteTypeProduct(IInstance instance);

deriveMappedShapeFromShape()#

IInstance deriveMappedShapeFromShape(IInstance shape, [ double scale = 1.0])
Implementation
IInstance deriveMappedShapeFromShape(IInstance shape, [double scale = 1.0]);

exportModel() inherited#

bool exportModel(String filePath, ExportFormat format)

Exports the model to the specified file path in the given format.

This method serializes the entire model and writes it to the specified filePath in the requested format. The export includes all instances, relationships defined in the primary schema of the model.

Supported formats:

  • ExportFormat.csv: ISO 10303-21 standard (STEP Physical File format) for model exchange with other IFC/STEP-compliant applications. This is the industry standard format for data exchange.

  • ExportFormat.json: Experimental JSON encoding suitable for web-based applications and REST APIs.

  • ExportFormat.pib: PIComposer proprietary binary format for backup and internal model exchange within the PIComposer application ecosystem. Provides optimal performance and complete semantic preservation but is not compatible with external applications.

Parameters:

  • filePath: The complete path and filename where the model should be exported. The directory must exist and be writable.
  • format: The export format to use. See ExportFormat enum for options.

Returns true if the export was successful, or false otherwise Example usage:

// Export to ISO 10303-21 standard format for external exchange
final success1 = exportModel('/projects/buildingA.ifc', ExportFormat.csv);
if (success1) {
  print('Model exported to ISO 10303-21 format successfully');
  // File can now be shared with Revit, ArchiCAD, etc.
} else {
  print('ISO 10303-21 export failed');
}

// Export to JSON for web application consumption
final success2 = exportModel('/projects/buildingA.json', ExportFormat.json);
if (success2) {
  print('Model exported to JSON format successfully');
  // File can be loaded by web applications or used for debugging
} else {
  print('JSON export failed');
}

// Export to PIComposer binary for backup
final success3 = exportModel('/backups/buildingA.pib', ExportFormat.pib);
if (success3) {
  print('Model backed up to PIComposer binary format');
  // File can be quickly reloaded in PIComposer with full fidelity
} else {
  print('PIB export failed');
}

Inherited from IModel.

Implementation
bool exportModel(String filePath, ExportFormat format);

getAbsolutePlacement() extension#

Matrix4 getAbsolutePlacement(IInstance instance)

Gets the absolute transformation matrix for an IfcProduct instance.

Supports local placements and grid placements with polyline grids. Returns identity matrix for unsupported placement types.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
Matrix4 getAbsolutePlacement(IInstance instance) {
  var result = Matrix4.identity();
  final placement = getInstancePlacement(instance);
  if (placement.isNull) {
    return result;
  }
  List<IInstance> placements = <IInstance>[];
  final typeId = placement.typeId;
  if (typeId == GridPlacementId) {
    final relativeTo =
        placement.getInstance(attName: 'PlacementRelTo', resolveRef: true);
    if (relativeTo.isNull || relativeTo.typeId != LocalPlacementId) {
      return result;
    }
    placements = getPlacementHierarchy(relativeTo);
    final reverse = placements.reversed;
    for (final p in reverse) {
      final m = placementToMatrix(p);
      if (m.isIdentity()) {
        continue;
      }
      result.multiply(m);
    }
    &#47;&#47; get grid axes intersections..
    final pLocation =
        placement.getInstance(attName: 'PlacementLocation', resolveRef: true);
    if (pLocation.isNull) {
      return result;
    }
    final location = getVirtualGridIntersection(pLocation);
    if (!isZero(location)) {
      final translate =
          Matrix4.translation(Vector3(location.x, location.y, location.z));
      translate.multiply(result);
      return translate;
    }
    return result;
  } else if (typeId == LocalPlacementId) {
    placements = getPlacementHierarchy(placement);
    final reverse = placements.reversed;
    for (final p in reverse) {
      final m = placementToMatrix(p);
      if (m.isIdentity()) {
        continue;
      }
      result.multiply(m);
    }
    return result;
    &#47;&#47; linear placement (not supported)...
  } else {
    return result;
  }
}

getAllChildrenTypes()#

List<int> getAllChildrenTypes(IInstance instance)

Gets all spatial child types present under the specified instance.

This method examines only the immediate children of the given instance in the spatial hierarchy and returns a list of all unique IFC types found among these direct child instances. This is useful for analyzing the direct composition of a spatial structure.

Returns a list of unique IFC type identifiers (integers), or an empty list if:

  • The instance handle is invalid
  • The instance has no immediate spatial children
  • The immediate children have no valid types

Example usage:

final buildingStorey = getInstance(storeyHandle);
final immediateChildTypes = getAllChildrenTypes(buildingStorey);

if (immediateChildTypes.isNotEmpty) {
  print('Building storey contains direct children of types:');
  final schema = getSchema();
  for (final typeId in immediateChildTypes) {
    final typeName = schema.getTypeName(typeId);
    print('  - $typeName (ID: $typeId)');
  }
} else {
  print('Building storey has no immediate spatial children');
}

// Use case: Check what types of elements are directly placed on this storey
if (immediateChildTypes.contains(toTypeId('IfcSlab'))) {
  print('This storey contains slab elements');
}
Implementation
List<int> getAllChildrenTypes(IInstance instance);

getAttributeByPath() inherited#

Record getAttributeByPath(InstancePath path)

Gets an attribute value using a path specification.

This method retrieves values from deep within complex instance hierarchies by specifying a navigation path to the target attribute. It returns both the value and its fundamental type, providing complete type information for proper handling of the retrieved data.

The path can traverse through multiple levels of:

  • Instance attributes (by name)
  • Select type selections (using the selected type name)
  • Aggregate elements (using integer indices for LIST, SET, ARRAY)

Together with setAttributeByPath and getAttributeContainer, this method provides a comprehensive way to inspect and manipulate complex instance structures without manual traversal.

Parameters:

  • path: An InstancePath object specifying the navigation path to the target attribute. The path consists of a starting instance handle and a list of path components (strings for attributes, integers for aggregates).

Returns a tuple (FundamentalType, dynamic) where:

  • FundamentalType: The fundamental type of the retrieved value, which determines how the value should be interpreted and handled
  • dynamic: The actual value at the specified path, whose type corresponds to the fundamental type

Returns (FundamentalType.UNKNOWN, null) if:

  • The path is invalid or cannot be resolved
  • The target attribute does not exist
  • Any intermediate object in the path is null or invalid
  • The path index is out of bounds for aggregate attributes

Example usage:

// Get a nested attribute with type information
final path = InstancePath(
  wallHandle,
  ['ObjectPlacement', 'RelativePlacement', 'IfcAxis2Placement3D', 'Location']
);

final (type, value) = getAttributeByPath(path);

if (type != FundamentalType.UNKNOWN) {
  print('Found value of type: $type');
  if (type == FundamentalType.ENTITY) {
    final location = value as IInstance;
    print('Location instance: ${location.typeName}');
  }
} else {
  print('Path not found or invalid');
}

Inherited from IModel.

Implementation
(FundamentalType, dynamic) getAttributeByPath(InstancePath path);

getAttributeByPathAsDynamic() inherited#

dynamic getAttributeByPathAsDynamic(InstancePath path)

Gets an attribute value using a path specification as a dynamic value.

This method retrieves values from deep within complex instance hierarchies by specifying a navigation path to the target attribute. It returns only the value without the fundamental type information, making it simpler to use when type information is not required.

This is a convenience wrapper around getAttributeByPath that discards the type information for simpler use cases.

Parameters:

  • path: An InstancePath object specifying the navigation path to the target attribute. The path consists of a starting instance handle and a list of path components (strings for attributes, integers for aggregates).

Returns the value at the specified path as a dynamic value, or null if:

  • The path is invalid or cannot be resolved
  • The target attribute does not exist
  • Any intermediate object in the path is null or invalid
  • The path index is out of bounds for aggregate attributes

Example usage:

// Simple value retrieval when type is known
final path = InstancePath(
  wallHandle,
  ['Name'] // Known to be a string
);

final name = getAttributeByPathAsDynamic(path) as Option<String>?;
if (name != null) {
  print('Wall name: $name.getOrElse(() => '')');
}

Inherited from IModel.

Implementation
dynamic getAttributeByPathAsDynamic(InstancePath path);

getBody3dGeometricContext() extension#

IInstance getBody3dGeometricContext()

Gets the 3D geometric representation context for body shapes. Prefers subcontexts with 'Body' identifier, falls back to model context.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance getBody3dGeometricContext() {
  final contexts =
      getInstancesByType(typeId: GeometricRepresentationSubContextId);
  IInstance candidate = createNullInstance();
  for (final context in contexts) {
    final type =
        context.getString(attName: 'ContextType').getOrElse(() => '');
    if (type.isEmpty) {
      continue;
    }
    final identifier =
        context.getString(attName: 'ContextIdentifier').getOrElse(() => '');
    if (identifier.isEmpty) {
      continue;
    }
    final dim = context
        .getInt(attName: 'CoordinateSpaceDimension')
        .getOrElse(() => 0);
    final view = context.getEnum(attName: 'TargetView');
    if ((view.stringValue.toUpperCase() == 'MODEL_VIEW') &&
        (type.toLowerCase() == 'model') &&
        (identifier.toLowerCase() == 'body') &&
        (dim == 3)) {
      return context;
    } else if ((view.stringValue.toUpperCase() == 'MODEL_VIEW') &&
        (type.toLowerCase() == 'model') &&
        (identifier.toLowerCase() == 'body')) {
      candidate = context;
    }
  }
  return candidate;
}

getHeader() inherited#

IInstance getHeader()

Gets the header instance containing model metadata.

This method retrieves the header instance that contains essential metadata about the model, including file description, naming information, and schema details. The header follows the ISO 10303-21 (STEP) file structure and is typically created during model initialization.

The header instance contains three main attributes:

  1. file_description - Implementation level and description
  2. file_name - Name, timestamp, author, organization, and system information
  3. file_schema - Schema identifiers and version information

See IModelExtension.createHeader for details on how the header structure is created and the specific information captured in each attribute.

Returns the header IInstance if it exists, or null instance.

Inherited from IModel.

Implementation
IInstance getHeader();

getHeaderClearTextRepresentation() inherited#

String getHeaderClearTextRepresentation(ExportFormat type)

Gets the string representation of the header instance in the specified format.

This method serializes the model header information into a human-readable string format suitable for display, export, or debugging. The header contains essential metadata about the model including file description, naming information, and schema details.

Supported formats:

  • ExportFormat.csv: Generates the HEADER section of an ISO 10303-21 (STEP) Part 21 file. This includes the standardized header structure with FILE_DESCRIPTION, FILE_NAME, and FILE_SCHEMA sections in the exact format required by the ISO standard.

  • ExportFormat.json: Generates a JSON representation of the header information suitable for web applications, APIs, or debugging. Provides a structured hierarchical view of the header data.

Together with IInstance.getClearTextRepresentation, this method enables users to implement custom export logic by combining the header content with individual instance representations to create complete model exports.

Parameters:

Returns a string containing the header representation in the requested format. Returns an empty string if:

  • The header instance is missing or invalid

Inherited from IModel.

Implementation
String getHeaderClearTextRepresentation(ExportFormat type);

getIfcProject()#

IInstance getIfcProject()

Retrieves the IfcProject instance from the model.

Returns the root IInstance IfcProject.

There is one and only one IfcProject instance per model, as required by the IFC specification. This method returns that single instance.

Returns null instance if no IfcProject exists in the model. In this case, call IfcModelExtension.createIfcProject to create a default IfcProject instance before attempting to retrieve it.

The IfcProject is required for most IFC operations as it contains essential context information and serves as the entry point for the spatial hierarchy.

Implementation
IInstance getIfcProject();

getInfo() inherited#

ModelInfo getInfo()

Gets generic information about the model as a ModelInfo object.

Inherited from IModel.

Implementation
ModelInfo getInfo();

getInstance() inherited#

IInstance getInstance(InstanceHandle instance)

Gets an instance from the database by its persistent handle.

This method retrieves the instance corresponding to the specified instance handle from the database or in-memory storage.

For database-backed models, this may involve a database query to load the instance data. For memory-only models, this retrieves the instance from the in-memory collection.

If the handle is invalid, or refers to a non-existent instance, null instance is returned. You should always check IInstance.isNull on the returned object before using it.

Inherited from IModel.

Implementation
IInstance getInstance(InstanceHandle instance);

getInstancePlacement() extension#

IInstance getInstancePlacement(IInstance inst)

Gets the object placement instance for an IfcProduct.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
IInstance getInstancePlacement(IInstance inst) {
  final placement = inst.getInstance(attName: 'ObjectPlacement');
  if (placement.isNull || !placement.isInstanceReference) {
    return placement;
  }
  final handle = placement.instanceHandle;
  return getInstance(handle);
}

getInstanceRelations()#

List<IInstance> getInstanceRelations( IInstance instance, { int? relTypeId, String? relType, bool bIncludeSub = false, });

Gets instances related to the specified instance by relation type.

This method retrieves all instances that are related to the specified instance through relationships of the given relTypeId. The method can optionally include subtypes of the specified relation type when bIncludeSub is true.

Returns a list of related instance handles, or an empty list if:

  • The instance handle is invalid
  • No relationships of the specified type exist for this instance

Example usage:

// Get all IfcRelDefinesByProperties relationships for a wall
final propRelHandles = getInstanceRelation(
  wallInstance.instanceHandle,
  toTypeId('IfcRelDefinesByProperties'),
  bIncludeSub: false,
);

// Get all relationship types (including subtypes) for a wall
final allRelHandles = getInstanceRelation(
  wallInstance,
  toTypeId('IfcRelDefines'),
  bIncludeSub: true,
);

for (final relHandle in allRelHandles) {
  final rel = getInstance(relHandle);
  print('Relationship type: ${rel.typeName}');
}
Implementation
List<IInstance> getInstanceRelations(IInstance instance,
    {int? relTypeId, String? relType, bool bIncludeSub = false});

getInstances() inherited#

List<InstanceHandle> getInstances()

Gets all instance handles in the model.

This method retrieves handles for every instance currently in the model. The returned list can be used to access, process, or iterate over all instances in the model.

⚠️ Performance Warning: This method should not be used for large models as it may cause significant memory usage and performance degradation. For models containing more than a few thousand instances, use the paginated API getInstancesPaginated instead.

Returns an empty list if the model contains no instances or if the model is not properly initialized.

Inherited from IModel.

Implementation
List<InstanceHandle> getInstances();

getInstancesByFilter() inherited#

List<IInstance> getInstancesByFilter( List<int> ids, List<IdRange> range, int type, );

Gets instances filtered by ID lists and/or ID ranges for a specific type.

This method retrieves instances of the specified type that match either the explicit ids list or fall within the specified range intervals.

Parameters:

  • ids: A list of specific instance IDs to retrieve. Empty list means no ID filtering.
  • range: A list of IdRange objects defining inclusive ID ranges to retrieve. Empty list means no range filtering.
  • type: The type ID of instances to retrieve. Use toTypeId() to convert type names.

Returns a list of IInstance objects that match the filter criteria. Returns an empty list if no instances match the filters or if the type has no instances.

Inherited from IModel.

Implementation
List<IInstance> getInstancesByFilter(
    List<int> ids, List<IdRange> range, int type);

getInstancesByHandle() inherited#

List<IInstance> getInstancesByHandle(List<InstanceHandle> handles)

Gets instances from the database by their persistent handles.

Inherited from IModel.

Implementation
List<IInstance> getInstancesByHandle(List<InstanceHandle> handles);

getInstancesByTag() inherited#

List<IInstance> getInstancesByTag(String tag)

Gets all instances with the given tag.

This method retrieves all instances that have been tagged with the specified tag string using the tagInstance method. Each instance can have only one tag at a time - setting a new tag replaces any existing tag.

Tags are not case-sensitive. The search will match tags regardless of capitalization. The method returns actual IInstance objects rather than handles, making it convenient for immediate processing of tagged instances.

Parameters:

  • tag: The tag string to search for. Tag matching is case-insensitive.

Returns a list of IInstance objects that have been tagged with the specified tag (case-insensitive match). Returns an empty list if no instances have the tag.

Inherited from IModel.

Implementation
List<IInstance> getInstancesByTag(String tag);

getInstancesByType() inherited#

List<IInstance> getInstancesByType({ int? typeId, String? typeName, bool includeSubType = false, });

Gets all instances of a given type.

This method retrieves all instances that match the specified typeId. When includeSubType is true, it also includes instances of all subtypes that inherit from the specified type, providing a hierarchical query capability.

The returned instances are ordered according to the same sorting as getInstancesPaginated: first by typeId, then by instanceId.

Parameters:

  • typeId: The type identifier to filter instances by. Use toTypeId() to convert a type name to its corresponding ID.
  • includeSubType: When true, includes instances of all subtypes that inherit from the specified type. When false, returns only exact matches.

Returns a list of instance handles matching the type criteria. Returns an empty list if no instances of the specified type (and subtypes, if enabled) exist in the model.

⚠️ Performance Note: For types with many instances or deep inheritance hierarchies, this method may be expensive. Consider using paginated approaches for very large result sets by using InstanceHandle(typeId, 0) as startingHandle to call getInstancesByTypePaginated.

Inherited from IModel.

Implementation
List<IInstance> getInstancesByType(
    {int? typeId, String? typeName, bool includeSubType = false});

getInstancesByTypePaginated() inherited#

List<IInstance> getInstancesByTypePaginated( InstanceHandle startHandle, int pageSize, { int? typeId, String? typeName, bool includeSubType = false, });

Gets all instances of a given type.

This method retrieves all instances that match the specified typeId. When includeSubType is true, it also includes instances of all subtypes that inherit from the specified type, providing a hierarchical query capability.

The returned instances are ordered according to the same sorting as getInstancesPaginated: first by typeId, then by instanceId.

Parameters:

  • typeId: The type identifier to filter instances by. Use toTypeId() to convert a type name to its corresponding ID.
  • includeSubType: When true, includes instances of all subtypes that inherit from the specified type. When false, returns only exact matches.
  • pageSize: The number of return value per page, the maximum size is 2000.

Returns a list of instance handles matching the type criteria. Returns an empty list if no instances of the specified type (and subtypes, if enabled) exist in the model.

⚠️ Performance Note: For types with many instances or deep inheritance hierarchies, this method may be expensive. Consider using paginated approaches for very large result sets by using InstanceHandle(typeId, 0) as startingHandle to call getInstancesByTypePaginated.

Inherited from IModel.

Implementation
List<IInstance> getInstancesByTypePaginated(
    InstanceHandle startHandle, int pageSize,
    {int? typeId, String? typeName, bool includeSubType = false});

getInstancesPaginated() inherited#

List<IInstance> getInstancesPaginated( InstanceHandle startingHandle, { int pageSize = 2000, });

Gets instances paginated for efficient handling of large models.

This method retrieves instances in manageable chunks (pages) to avoid memory overload and performance issues when working with large models. It is the recommended alternative to getInstances for models containing more than a few thousand instances.

The paging order is determined by the InstanceHandle's comparison operator, which sorts instances first by typeId and then by instanceId. This ensures consistent ordering across pagination requests.

Parameters:

  • startingHandle: The handle to start pagination from. Use InstanceHandle.nullHandle() for the first page. For subsequent pages, use the last handle from the current page.
  • pageSize: The number of instances to retrieve per page. Defaults to 2000, the maximum page size. Adjust based on available memory and performance requirements.

Returns a list of instance handles for the current page, sorted by typeId then instanceId. Returns an empty list when no more instances are available (end of model reached).

Example usage:

// Paginate through all instances sorted by typeId then instanceId
InstanceHandle currentHandle = InstanceHandle.nullHandle();
int totalProcessed = 0;
do {
  final pageHandles = getInstancesPaginated(currentHandle, pageSize: 250);
  if (pageHandles.isEmpty) break;
  for (final handle in pageHandles) {
    final instance = getInstance(handle);
    // do something with instance
    processInstance(instance);
    totalProcessed++;
  }
  currentHandle = pageHandles.last;
} while (true);

Inherited from IModel.

Implementation
List<IInstance> getInstancesPaginated(InstanceHandle startingHandle,
    {int pageSize = 2000});

getInstanceTypes() inherited#

List<String> getInstanceTypes({ bool sorted = false})

Gets a list of all instance types that appear at least once in the model.

  • sorted: When true, returns the type names in alphabetical order.

Inherited from IModel.

Implementation
List<String> getInstanceTypes({bool sorted = false});

getLayers()#

List<IInstance> getLayers(IInstance instance)

Gets all layers associated with an instance.

This method retrieves all presentation layers (IfcPresentationLayerAssignment or IfcPresentationLayerWithStyle) that are associated with the specified instance. The instance can be any IFC entity that can be assigned to layers, typically IfcShapeRepresentation or other representation entities.

Returns a list of layer instance handles, or an empty list if:

  • The instance handle is invalid
  • No layers are associated with this instance

Example usage:

final wallShape = getShapes(wallInstance.instanceHandle).first;
final layerHandles = getLayers(wallShape);

if (layerHandles.isNotEmpty) {
  for (final layerHandle in layerHandles) {
    final layer = getInstance(layerHandle);
    final layerName = layer.getString(attName: 'Name');
    print('Instance is on layer: $layerName');
  }
} else {
  print('Instance is not assigned to any layers');
}
Implementation
List<IInstance> getLayers(IInstance instance);

getLocation() inherited#

String getLocation()

Gets the database location/path of this model.

Inherited from IModel.

Implementation
String getLocation();

getMatchingContext()#

IInstance getMatchingContext(IInstance geoRepContext)

Finds the IfcGeometricRepresentationContext in this model that most closely matches the provided geoRepContext.

This is an important method for inter-model operations. The input geoRepContext should typically be from another model or an IBlocklyTemplate.

The method compares context attributes such as:

  • ContextType (e.g., 'Model', 'Plan', 'Annotation')
  • Coordinate space dimension (2D vs 3D)
  • Precision value
  • World coordinate system parameters

Returns null instance if no matching context is found. In this case, operations such as copy-paste and template instantiation should not proceed, as significant coordinate system or unit discrepancies may exist between the models.

A matching context ensures geometric consistency when transferring elements between models or instantiating templates.

Implementation
IInstance getMatchingContext(IInstance geoRepContext);

getMaterials()#

List<IInstance> getMaterials(IInstance instance)

Gets all IfcRelAssociatesMaterial relationships associated with an instance.

This method retrieves all IfcRelAssociatesMaterial relationships that are associated with the specified instance. Each relationship contains a reference to an IfcMaterial or other material definition that defines the material properties for this instance.

Returns a list of IfcRelAssociatesMaterial instance handles, or an empty list if:

  • The instance handle is invalid
  • No material associations exist for this instance

Example usage:

final materialRelationships = getMaterials(wallInstance);
for (final relHandle in materialRelationships) {
  final rel = getInstance(relHandle);
  final matSel = rel.getSelect(attName: 'RelatingMaterial');
  if (matSel.isNull) {
    continue;
  }
  // get the selected material type
  if (matSel.selectedTypeName.toLowerCase() == 'ifcmaterial') {
    final material = matSel.getInstance();
    final materialName = material.getString(attName: 'Name');
    print('Material: $materialName');
  } else if (matSel.selectedTypeName.toLowerCase() == 'ifcmateriallayersetusage') {
    // Handle other material selection types (IfcMaterialList, IfcMaterialLayerSet, etc.)
    final materials = matSel.getInstances();
    for (final mat in materials) {
      print('Material component: ${mat.getString(attName: "Name")}');
    }
  } else {
    // process other selected types
  }
}
Implementation
List<IInstance> getMaterials(IInstance instance);

getModelLengthUnit() inherited#

IInstance getModelLengthUnit()

Gets the length unit instance defined in this model's IfcUnitAssignment.

This method retrieves the length unit instance that represents the base measurement unit for all geometric data in the model. The length unit is typically defined in the model's IfcUnitAssignment and is essential for ensuring consistent interpretation of dimensional values throughout the model.

The returned instance is usually of type IfcSIUnit (e.g., METER, MILLIMETER) or IfcConversionBasedUnit for custom unit definitions.

Returns the length unit IInstance if found in the model's unit assignment. Returns null instance if error See also:

Inherited from IModel.

Implementation
IInstance getModelLengthUnit();

getOneInstanceOfType() inherited#

IInstance getOneInstanceOfType({ int? typeId, String? typeName})

get one instance of a given type.

Inherited from IModel.

Implementation
IInstance getOneInstanceOfType({int? typeId, String? typeName});

getPlacementChildren()#

List<IInstance> getPlacementChildren(IInstance parent)

Retrieves children in the placement hierarchy for the given parent placement.

This method returns all direct child instances that are linked through placement relationships (IfcLocalPlacement) to the specified parent.

The placement hierarchy represents the coordinate system relationships between objects, where child placements are relative to their parent's coordinate system.

Returns an empty list if the parent has no placement children or if the parent handle is invalid.

Example usage:

final buildingPlacement = getPlacement(building);
final placementChildren = getPlacementChildren(buildingPlacement);
for (final childPlacement in placementChildren) {
  final placements = getPlacementHierarchy(childPlacement);
  // Process child objects in global coordinate space
}
Implementation
List<IInstance> getPlacementChildren(IInstance parent);

getPlacementHierarchy() extension#

List<IInstance> getPlacementHierarchy(IInstance instance)

Gets the relative placement hierarchy for a local placement instance.

instance must be an IfcLocalPlacement. Returns empty list for invalid placements or infinite loops.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
List<IInstance> getPlacementHierarchy(IInstance instance) {
  final result = <IInstance>[];
  if (instance.typeId != LocalPlacementId) {
    return result;
  }
  try {
    IInstance current = instance;
    result.add(current);
    while (!current.isNullAttribute(attIndex: 0).getOrElse(() => true)) {
      &#47;&#47; get relativeTo ref...
      final relatedTo = current.getInstance(attIndex: 0);
      if (relatedTo.referencedTypeId != LocalPlacementId) {
        return [];
      }
      current = getInstance(relatedTo.instanceHandle);
      final id =
          result.indexWhere((inst) => inst.instanceId == current.instanceId);
      &#47;&#47; infinite loop
      if (id > -1) {
        return [];
      }
      result.add(current);
    }
  } catch (e) {
    return result;
  }
  return result;
}

getProjectRelDeclares()#

List<IInstance> getProjectRelDeclares()

Get all relation of type IfcRelDeclares relating to IfcProject.

Implementation
List<IInstance> getProjectRelDeclares();

getPSets()#

List<IInstance> getPSets(IInstance instance)

Gets all property sets (IfcRelDefinesByProperties relationships) associated with an instance.

This method retrieves all IfcRelDefinesByProperties relationships that are associated with the specified instance.

Returns a list of IfcRelDefinesByProperties instances, or an empty list if:

  • The instance handle is invalid
  • No property set associations exist for this instance

Example usage:

final psetRelationships = getPSets(wallInstance);
for (final rel in psetRelationships) {
  final propSel = rel.getSelect(attName: 'RelatingPropertyDefinition');
  // propSel is an ISelect
  if (propSel.isNull) {
    continue;
  }
  // get the selected type:
  if (propSel.selectedTypeName.toLowerCase() == 'ifcpropertysetdefinition') {
    // get select content
    final propDef = propSel.getInstance();
    final psetName = propDef.getString(attName: 'Name');
    print('Property set: $psetName');

    final properties = propDef.getInstances(attName: 'HasProperties');
    for (final prop in properties) {
      print('  - ${prop.getString(attName: "Name")}');
    }
  } else {
    final propDefs = propSel.getInstances();
    for (final propDef in propDefs) {
      // Process alternative property definition types
    }
  }
}
Implementation
List<IInstance> getPSets(IInstance instance);

getReferencingInstances() inherited#

List<InstanceHandle> getReferencingInstances(IInstance inst)

Gets all instances that reference the specified instance.

This method performs an inverse relationship query to find all instances in the model that contain references to the specified inst.

The method is useful for:

  • Dependency analysis before deleting instances
  • Understanding how an instance is used throughout the model
  • Identifying relationships that might be affected by instance modifications
  • Debugging reference integrity issues

Parameters:

  • inst: The target instance to find references for.

Returns a list of InstanceHandle objects representing all instances that reference the specified inst.

Inherited from IModel.

Implementation
List<InstanceHandle> getReferencingInstances(IInstance inst);

getRelatingSpatialRelations()#

List<IInstance> getRelatingSpatialRelations( IInstance instance, [ int relType = 0, ]);

get the relations that defined the parent and child spatial relation where instance is the parent.

Implementation
List<IInstance> getRelatingSpatialRelations(IInstance instance,
    [int relType = 0]);

getShapes()#

List<IInstance> getShapes(IInstance instance)

Gets all shape representations associated with the instance.

Returns a list of all IfcProductRepresentation objects (typically IfcProductDefinitionShape) that define the geometric representation of the specified instance.

Shapes may include multiple representations such as:

  • Body (3D geometry)
  • Axis (parametric representation)
  • Box (bounding box)
  • FootPrint (2D footprint)
  • Reference (reference geometry)

Each shape representation can contain multiple representation items (e.g., IfcExtrudedAreaSolid, IfcBooleanResult, IfcMappedItem).

Returns an empty list if the instance has no shape representations or if the instance handle is invalid.

Example usage:

final wallShapes = getShapes(wallInstance);
for (final shape in wallShapes) {
  final repType = shape.getAttribute('RepresentationType');
  // Process each geometric representation
}
Implementation
List<IInstance> getShapes(IInstance instance);

getShapesInLayer() extension#

List<IInstance> getShapesInLayer(IInstance layer)

Gets all shape representations in a specific layer.

Available on IIfcModel, provided by the IfcModelExtension extension

Implementation
List<IInstance> getShapesInLayer(IInstance layer) {
  final handles = <InstanceHandle>[];
  if (layer.isNull) {
    return [];
  }
  final shapeSels = layer.getSelects(attName: 'AssignedItems');
  for (final sel in shapeSels) {
    final shape = sel.getInstance();
    handles.add(shape.instanceHandle);
  }
  return getInstancesByHandle(handles);
}

getSpatialChildren()#

List<IInstance> getSpatialChildren(IInstance parent)

Gets all spatial children of the specified parent instance.

This is a key method for spatial hierarchy traversal and navigation. Returns a list of all direct child instances that are part of the spatial structure hierarchy under the given parent.

The method searches through all relevant spatial relationship types:

  • IfcRelContainedInSpatialStructure (for contained elements)
  • IfcRelAggregates (for decomposed spatial elements)
  • IfcRelVoidsElement (for opening elements)
  • IfcRelFillsElement (for fill elements)

Typical spatial hierarchy structure:

  • IfcProject → IfcSite → IfcBuilding → IfcBuildingStorey → IfcBuiltElement (IfcSlab, IfcWall, etc)

Returns an empty list if the parent has no spatial children or if the parent handle is invalid.

Example usage for hierarchy traversal:

final buildingStoreys = getSpatialChildren(building);
for (final storey in buildingStoreys) {
  final elements = getSpatialChildren(storey);
  for (final element in elements) {
    final psets = getPSets(element.instanceHandle);
    final shapes = getShapes(element.instanceHandle);
    // Process properties and geometry
  }
}
Implementation
List<IInstance> getSpatialChildren(IInstance parent);

getSpatialParent()#

IInstance getSpatialParent(IInstance child)

get spatial parent of a given instance.

Implementation
IInstance getSpatialParent(IInstance child);

getTypeCount() inherited#

int getTypeCount(int typeId, { bool includeSubType = false})

Gets the approximate count of instances of the given type.

This method returns an approximate count of instances for the specified typeId. The count is based on metadata that tracks type distributions and is optimized for performance rather than absolute accuracy. For absolutely accurate counts, use getInstancesByType.length, but note this has significant performance implications for types with many instances.

Parameters:

  • typeId: The type identifier to count instances for. Use toTypeId() to convert type names to IDs.
  • includeSubType: When true, includes instances of all subtypes that inherit from the specified type. When false, counts only exact matches.

Returns an approximate count of instances for the specified type. Returns 0 if the type has no instances, the type doesn't exist, or the metadata hasn't been initialized.

Inherited from IModel.

Implementation
int getTypeCount(int typeId, {bool includeSubType = false});

getTypeProduct()#

IInstance getTypeProduct(IInstance instance)

Gets the IfcRelDefinesByType relationship associated with an instance.

Returns the IfcRelDefinesByType relationship instance that links the specified instance to its type product, or null instance if:

  • The instance handle is invalid
  • No IfcRelDefinesByType relationship exists for this instance

Example usage:

final wallTypeRel = getTypeProduct(wallInstance.instanceHandle);
if (!wallTypeRel.isNull) {
  print('Wall type relationship: ${wallTypeRel.getAttribute("Name")}');
} else {
  print('Wall instance has no associated type product relationship');
}
Implementation
IInstance getTypeProduct(IInstance instance);

hasSameLengthUnit() inherited#

bool hasSameLengthUnit(IModel model)

Checks if another model uses the same length unit as this model.

This method compares the length unit definition of this model with another model to determine if they use compatible measurement units. This is essential when merging models, exchanging data, or performing cross-model geometric operations to ensure dimensional consistency.

The comparison is based on the actual unit definition and conversion factors, not just unit names, ensuring accurate compatibility checking even for different unit representations that measure the same quantity.

Parameters:

  • model: The other model to compare against. Must be a valid, initialized model.

Returns true if both models use the same length unit definition (equivalent measurement units) See also:

Inherited from IModel.

Implementation
bool hasSameLengthUnit(IModel model);

incrementTypeCount() inherited#

int incrementTypeCount(int typeId)

Increments the type count for a specific type.

This method manually increases the metadata counter for the specified typeId. It is automatically called internally by saveInstance and saveInstances when new instances are persisted to the database, ensuring type counts are maintained for approximate counting via getTypeCount.

⚠️ Manual Use Warning: This method should generally not be called manually unless you are implementing custom instance creation logic that bypasses the standard saveInstance mechanism. Improper use can lead to inaccurate type counts and metadata inconsistencies.

Parameters:

  • typeId: The type identifier to increment. Use toTypeId() to convert type names to IDs.

Returns the new count after incrementing

Inherited from IModel.

Implementation
int incrementTypeCount(int typeId);

initialize() inherited#

FutureOr<void> initialize(dynamic parameter)

Initializes the model with the given parameters. Currently not in use.

Inherited from IModel.

Implementation
FutureOr<void> initialize(dynamic parameter);

instanceFromJson() inherited#

IInstance instanceFromJson(Map<String, dynamic> json)

Creates an instance declaratively from JSON data.

This method provides a convenient way to create IFC instances using a JSON-like structure that mirrors the object composition hierarchy. It handles the complete instantiation process including object creation, attribute setting, and relationship establishment.

The JSON structure uses special keys and conventions:

  • '@type': Specifies the IFC type name for the instance (required for root objects)
  • Nested objects: Represent composed child instances or complex attributes
  • Arrays: Represent aggregate attributes (LIST, SET, ARRAY)
  • Select types: Use the selected type name as key with object as value

Parameters:

  • json: A JSON-like map representing the instance structure and attributes. The map must contain at least an '@type' key for the root object.

Returns the created IInstance, or null instance if:

  • The '@type' key is missing or invalid
  • The JSON structure is malformed or inconsistent
  • Attribute values are incompatible with the target types

Example usage:

// Create a simple Cartesian point
final point = instanceFromJson({
  '@type': 'IfcCartesianPoint',
  'Coordinates': [1.0, 2.0, 3.0]
});

// Create property sets with complex values
final pset = instanceFromJson({
  '@type': 'IfcPropertySet',
  'Name': 'Pset_WallCommon',
  'HasProperties': [
    {
      '@type': 'IfcPropertySingleValue',
      'Name': 'Reference',
      'NominalValue': {
        'IfcSimpleValue' : {
          'IfcIdentifier': 'EXTERIOR_WALL_001'
         }
      }
    },
    {
      '@type': 'IfcPropertySingleValue',
      'Name': 'LoadBearing',
      'NominalValue': {
        'IfcSimpleValue' : {
            'IfcBoolean': true
         }
      }
    }
  ]
});

Inherited from IObjectFactory.

Implementation
IInstance instanceFromJson(Map<String, dynamic> json);

isReferenceType() inherited#

bool isReferenceType(int typeId)

Checks if a type is a reference type (should not be composed in instance attributes).

In IFC, reference types include:

  • IfcOwnerHistory, IfcPerson, IfcOrganization, IfcPersonAndOrganization
  • IfcApplication, IfcProject, IfcShapeRepresentation, IfcUnitAssignment
  • IfcGeometricRepresentationContext, IfcGeometricRepresentationSubContext
  • IfcLocalPlacement, IfcGridPlacement, IfcTask, IfcWorkCalendar
  • IfcGrid, IfcGridAxis, IfcStyledItem, IfcWorkPlan
  • All subtypes of: IfcProduct, IfcObjectPlacement, IfcRelationship, IfcPresentationLayerAssignment, IfcGroup

Inherited from IModel.

Implementation
bool isReferenceType(int typeId);

nextInstanceId() inherited#

int nextInstanceId([ bool incrementId = false])

Gets the next available instance identifier.

incrementId: If true, advances the internal ID counter after retrieval. If false, returns the next ID without changing the counter.

Returns the next available instance identifier that will be assigned.

Inherited from IObjectFactory.

Implementation
int nextInstanceId([bool incrementId = false]);

noSuchMethod() inherited#

dynamic noSuchMethod(Invocation invocation)

Invoked when a nonexistent method or property is accessed.

A dynamic member invocation can attempt to call a member which doesn't exist on the receiving object. Example:

dynamic object = 1;
object.add(42); // Statically allowed, run-time error

This invalid code will invoke the noSuchMethod method of the integer 1 with an Invocation representing the .add(42) call and arguments (which then throws).

Classes can override noSuchMethod to provide custom behavior for such invalid dynamic invocations.

A class with a non-default noSuchMethod invocation can also omit implementations for members of its interface. Example:

class MockList<T> implements List<T> {
  noSuchMethod(Invocation invocation) {
    log(invocation);
    super.noSuchMethod(invocation); // Will throw.
  }
}
void main() {
  MockList().add(42);
}

This code has no compile-time warnings or errors even though the MockList class has no concrete implementation of any of the List interface methods. Calls to List methods are forwarded to noSuchMethod, so this code will log an invocation similar to Invocation.method(#add, [42]) and then throw.

If a value is returned from noSuchMethod, it becomes the result of the original invocation. If the value is not of a type that can be returned by the original invocation, a type error occurs at the invocation.

The default behavior is to throw a NoSuchMethodError.

Inherited from Object.

Implementation
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
external dynamic noSuchMethod(Invocation invocation);

removeLayer()#

bool removeLayer(IInstance instance, IInstance layer)

Removes an instance from a layer.

This method disassociates the specified instance from the given presentation layer layer. The layer can be either an IfcPresentationLayerAssignment or IfcPresentationLayerWithStyle instance.

Returns true if the instance was successfully removed from the layer, or false if:

  • Either instance handle is invalid
  • The instance is not associated with the specified layer
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final wallShape = getShapes(wallInstance.instanceHandle).first;
final layerHandles = getLayers(wallShape.instanceHandle);

if (layerHandles.isNotEmpty) {
  final layerToRemove = getInstance(layerHandles.first);
  final success = removeLayer(wallShape, layerToRemove);

  if (success) {
    print('Instance successfully removed from layer');
  } else {
    print('Failed to remove instance from layer');
  }
}
Implementation
bool removeLayer(IInstance instance, IInstance layer);

removeMaterial()#

bool removeMaterial(IInstance instance, IInstance material)

Removes an IfcRelAssociatesMaterial relationship from an instance.

This method disassociates the specified material relationship material from the given instance. If the IfcRelAssociatesMaterial relationship no longer references any products after removal, it will be deleted from the database to maintain data integrity.

Returns true if the material association was successfully removed, or false if:

  • Either instance handle is invalid
  • The material association does not exist
  • The operation fails for any other reason

Changes are persisted to the database.

Example usage:

final materialRels = getMaterials(wallInstance.instanceHandle);
if (materialRels.isNotEmpty) {
  final materialRel = getInstance(materialRels.first);
  final success = removeMaterial(wallInstance, materialRel);
  if (success) {
    print('Material association removed successfully');
  } else {
    print('Failed to remove material association');
  }
}
Implementation
bool removeMaterial(IInstance instance, IInstance material);

removePSet()#

bool removePSet(IInstance instance, IInstance pset)

Removes a specific property set from an instance.

This method disassociates the property set relationship from the instance. If the IfcRelDefinesByProperties relationship no longer references any products, it will be removed from the database to maintain data integrity.

Changes to instance and pset are persisted to the database.

Returns true if the property set was successfully removed, or false if:

  • Either instance handle is invalid
  • The property set association does not exist
  • The operation fails for any other reason

Example usage:

final psetRelationships = getPSets(wallInstance.instanceHandle);
if (psetRelationships.isNotEmpty) {
  final success = removePSet(wallInstance, psetRelationships.first);
  if (success) {
    print('Property set removed successfully');
  } else {
    print('Failed to remove property set');
  }
}
Implementation
bool removePSet(IInstance instance, IInstance pset);

removeShape()#

bool removeShape(IInstance instance, IInstance shape)

Removes a specific shape representation from the instance.

This method removes a single shape representation from the instance's IfcProductRepresentation, identified by the shape handle.

The removal process:

  1. Disassociates the shape from the instance's "Representation" attribute
  2. If the shape is exclusively used by this instance and no other IfcProduct references it, the shape and its dependent geometry (representation items, styles, materials) are deleted from the model
  3. If the shape is shared by multiple instances, only the reference is removed while the geometry remains available for other instances
  4. Maintains database integrity by cleaning up inverse relationships

This operation automatically persists changes to the instance in the database. No additional call to saveInstance is required for the shape removal.

Returns true if the shape was successfully removed, or false if:

  • The instance handle is invalid
  • The shape handle is invalid or not associated with this instance

Use this for selective removal of specific representations when clearShapes would be too destructive.

Example usage:

// Get all shapes from an instance
final shapes = getShapes(wallInstance);

// Remove only the bounding box representation while keeping the body geometry
final boundingBoxShape = shapes.firstWhere(
  (shape) => shape.getAttribute('RepresentationType') == 'BoundingBox',
  orElse: () => nullInstance,
);

if (boundingBoxShape.isValid) {
  final success = removeShape(wallInstance, boundingBoxShape);
  if (success) {
    print('Bounding box representation removed successfully');
  }
}
Implementation
bool removeShape(IInstance instance, IInstance shape);

resolveIndex() inherited#

bool resolveIndex(IInstance instance)

Makes the instance's ID consistent with other instance IDs in the model.

This method ensures that the specified instance has an ID that is unique and consistent with the model's ID allocation scheme. The operation cascades recursively through the entire composition structure of the instance, including:

  • All composed child instances
  • All composites

This is typically used when:

  • manually copying instances between models
  • instance create from IInstance.duplicate resolve id consistency
  • Repairing models with ID conflicts or inconsistencies

The method performs a deep resolution, ensuring that all components of the instance hierarchy have consistent IDs that won't conflict with existing instances in the model.

Parameters:

  • instance: The instance to resolve. Must be a valid instance handle.

Returns true if the ID resolution was successful for the entire hierarchy, otherwise false.

Inherited from IModel.

Implementation
bool resolveIndex(IInstance instance);

resolveIndices() inherited#

bool resolveIndices(List<IInstance> instances)

Makes instance IDs in the list consistent with other instance IDs in the model.

This method ensures that all instances in the provided instances list have unique IDs that are consistent with the model's ID allocation scheme. The operation processes each instance and its entire composition hierarchy, similar to resolveIndex, but handles multiple instances in a single call.

Parameters:

  • instances: The list of instances to resolve.

Returns true if all instances and their hierarchies were successfully resolved, or false otherwise.

Inherited from IModel.

Implementation
bool resolveIndices(List<IInstance> instances);

resolveIndicesWithIds() inherited#

bool resolveIndicesWithIds(List<IInstance> instances, Map<int, int> ids)

Resolves instance IDs while mapping them using the provided ID map.

This method provides precise control over ID resolution by allowing explicit mapping of original IDs to new IDs using the provided ids mapping dictionary. For any instance ID not explicitly mapped in the ids dictionary, the method will automatically assign a new consistent ID to maintain model integrity.

The operation performs the following:

  1. Reassigns instance IDs according to the provided mapping for specified IDs
  2. Automatically generates consistent IDs for any unmapped instances
  3. Updates all internal references within the instance hierarchies
  4. Ensures consistency across the entire composition structure
  5. Validates that new IDs don't conflict with existing instances in the model

Parameters:

  • instances: The list of instances to resolve. These instances will have their IDs remapped according to the provided mapping or auto-assigned.
  • ids: A mapping dictionary where keys are original IDs and values are the new target IDs. Instances with IDs not in this map will receive automatically generated consistent IDs.

Returns true if all instances were successfully remapped and all references updated consistently, or false otherwise.

Inherited from IModel.

Implementation
bool resolveIndicesWithIds(List<IInstance> instances, Map<int, int> ids);

saveHeader() inherited#

void saveHeader()

Saves the header instance to the database.

Inherited from IModel.

Implementation
void saveHeader();

saveInstance() inherited#

bool saveInstance(IInstance instance, { String? tag})

Saves an instance to the database.

This method persists the specified instance to the underlying database storage. If this is a memory-only model, the method does nothing and returns true (as memory models don't require persistence).

The optional tag parameter allows you to associate a custom tag with the instance for later retrieval using getInstancesByTag. Tags are useful for categorizing instances or marking them for specific processing.

Returns true if the instance was successfully saved (or if this is a memory model), or false if:

  • The instance handle is invalid
  • The database operation fails

Example usage:

final wallInstance = createInstance(typeName: 'IfcWall');
wallInstance.setString('Exterior Wall', attName: 'Name');

// Save without tag
final success1 = saveInstance(wallInstance);
if (success1) {
  print('Wall instance saved successfully');
}

// Save with tag for easy retrieval
final success2 = saveInstance(wallInstance, tag: 'exterior_walls');
if (success2) {
  print('Wall instance saved and tagged');
}

// Later retrieve by tag
final exteriorWalls = getInstancesByTag('exterior_walls');
print('Found ${exteriorWalls.length} exterior walls');

Inherited from IModel.

Implementation
bool saveInstance(
  IInstance instance, {
  String? tag,
});

saveInstances() inherited#

bool saveInstances(List<IInstance> instances)

Saves multiple instances to the database in a batch operation.

This method persists a list of instances to the underlying database storage in a single transaction, which is significantly more efficient than saving instances individually. If this is a memory-only model, the method does nothing and returns true (as memory models don't require persistence).

The batch operation is atomic - either all instances are saved successfully or none are saved if an error occurs during the transaction.

Returns true if all instances were saved successfully (or if this is a memory model), or false if:

  • The entire batch operation fails
  • The database transaction cannot be completed

Example usage:

// Create multiple instances
final wall1 = createInstance(typeName: 'IfcWall')..setString('Wall 1', attName: 'Name');
final wall2 = createInstance(typeName: 'IfcWall')..setString('Wall 2', attName: 'Name');
final wall3 = createInstance(typeName: 'IfcWall')..setString('Wall 3', attName: 'Name');

final instancesToSave = [wall1, wall2, wall3];

// Save in batch for better performance
final success = saveInstances(instancesToSave);

if (success) {
  print('All ${instancesToSave.length} instances saved successfully in batch');
} else {
  print('Batch save operation failed - no instances were saved');
  // All instances remain unchanged and need to be handled individually
}

Inherited from IModel.

Implementation
bool saveInstances(List<IInstance> instances);

saveMetaData() inherited#

bool saveMetaData()

Saves metadata to the database.

This method persists model metadata to the database, including:

  • Entity types present in the model
  • Instance counts for each entity type
  • Schema version information
  • Model statistics and usage metrics

Metadata is used for efficient querying, reporting, and model analysis. It enables quick access to model composition without scanning all instances.

This method is called automatically in several scenarios:

  • During saveInstances operations to keep metadata synchronized
  • During database shutdown (Project.Uninitialize) to ensure final persistence

If this is a memory-only model, the method does nothing and returns true (as memory models don't require persistence).

Returns true if the metadata was successfully saved (or if this is a memory model), or else false.

While called automatically, you may want to call this method explicitly:

  • After bulk operations that bypass normal save mechanisms
  • Before generating reports that rely on accurate type counts
  • When manually modifying instance counts or model composition

Inherited from IModel.

Implementation
bool saveMetaData();

setAttributeByPath() inherited#

bool setAttributeByPath(InstancePath path, dynamic value)

Sets an attribute value using a path specification.

This method allows precise modification of nested attributes within complex instance hierarchies by specifying a path to the target attribute. The path can traverse through multiple levels of object composition, aggregate elements, select type selections and across instance boundaries.

The path follows the same structure as IInstance.setAttributeByPath, allowing you to navigate through:

  • Instance attributes (by name)
  • Select type selections (using the selected type name)
  • Aggregate elements (using integer indices for LIST, SET, ARRAY)

Together with getAttributeByPath and getAttributeContainer, this method provides a powerful way to manipulate complex instance structures without needing to manually traverse and extract intermediate objects.

Parameters:

  • path: An InstancePath object specifying the navigation path to the target attribute. The path consists of a starting instance handle and a list of path components (strings for attributes, integers for aggregates).
  • value: The value to set. The type must be compatible with the target attribute's fundamental type. For instance attributes, this can be an IInstance, ISelect, or primitive value. For aggregate elements, it must match the aggregate's element type.

Returns true if the attribute was successfully set, or false if:

  • The path is invalid or cannot be resolved
  • The target attribute does not exist
  • The value type is incompatible with the target attribute
  • The path traverses through null or invalid intermediate instance

Example usage:

// Set a nested attribute in a complex hierarchy
final attPath = ['RelativePlacement', 'IfcAxis2Placement2D', 'RefDirection'];
final handle = getInstancesByType(toTypeId('IfcLocalPlacement')).first;
final path = InstancePath(handle, attPath);

final refDir = instanceFromJson({
  '@type': 'IfcDirection',
  'DirectionRatios': [1.0, 0.0]
});

final success = setAttributeByPath(path, refDir);
if (success) {
  print('Reference direction set successfully');
} else {
  print('Failed to set reference direction');
}

Inherited from IModel.

Implementation
bool setAttributeByPath(InstancePath path, dynamic value);

setAttributeByPathWithJson() inherited#

bool setAttributeByPathWithJson( InstancePath path, Map<String, dynamic> json, );

Sets an attribute value using both path specification and JSON data.

This method combines the functionality of setAttributeByPath and JSON-based instance creation to provide a powerful way to set complex nested attributes using a declarative JSON structure. It navigates to the target attribute using the specified path and sets its value using the provided json data.

The method handles the complete process:

  1. Navigates through the instance hierarchy using the provided path
  2. Creates appropriate values from the JSON data (including nested instances)
  3. Sets the target attribute to the created value(s)

This is particularly useful for setting complex attributes that require creating nested object hierarchies or select type values.

Parameters:

  • path: An InstancePath object specifying the navigation path to the target attribute where the JSON value should be set.
  • json: A JSON-like map representing the value to set. The structure follows the same conventions as instanceFromJson, including support for: - '@type' key for entity instances
    • Nested objects for complex attributes
    • Arrays for aggregate values
    • Select type specifications

Returns true if the attribute was successfully set using the JSON data, or false if:

  • The path is invalid or cannot be resolved
  • The JSON structure is malformed or incompatible with the target attribute
  • The target attribute cannot accept the created value type
  • Any intermediate object in the path is null or invalid

Example usage:

// Set a complex placement attribute using JSON
final placementPath = InstancePath(wallHandle, ['ObjectPlacement', 'RelativePlacement',
   'IfcAxis2Placement3D', 'Location']);
final success = setAttributeByPathWithJson(placementPath, {
      '@type': 'IfcCartesianPoint',
      'Coordinates': [10.0, 5.0, 3.0]
});

if (success) {
  print('Complex placement hierarchy created and set successfully');
} else {
  print('Failed to set placement from JSON');
}

See also:

Inherited from IModel.

Implementation
bool setAttributeByPathWithJson(InstancePath path, Map<String, dynamic> json);

setInstanceRef() extension#

IInstance setInstanceRef( IInstance instance, IInstance ref, { String? attName, int? attIndex, bool addInverse = false, });

Available on IModel, provided by the IModelExtension extension

Implementation
IInstance setInstanceRef(IInstance instance, IInstance ref,
    {String? attName, int? attIndex, bool addInverse = false}) {
  if (instance.isNull || ref.isNull) {
    return createNullInstance();
  }

  final prevRef = instance.getInstance(attIndex: attIndex, attName: attName);
  IInstance prev = createNullInstance();
  if (!prevRef.isNull && prevRef.isInstanceReference) {
    prev = getInstance(prevRef.instanceHandle);
  }
  if (!prev.isNull) {
    prev.removeInverse(instance.instanceId);
  }
  instance.setInstanceRef(ref,
      attName: attName, attIndex: attIndex, addInverse: addInverse);
  return prev;
}

setModelLengthUnit()#

IInstance setModelLengthUnit(IInstance unitInst)

set model length unit with the new one. returns the old one if it exists. The returned unit might be part of IfcUnitAssignment composition, so no need to delete it.

Implementation
IInstance setModelLengthUnit(IInstance unitInst);

setNextInstanceId() inherited#

void setNextInstanceId(int nextId)

Sets the next instance identifier to use.

nextId: The next instance identifier value to set.

Use with caution: Setting this value affects all subsequent instance creations and may cause identifier conflicts if not managed carefully.

Inherited from IObjectFactory.

Implementation
void setNextInstanceId(int nextId);

tagInstance() inherited#

bool tagInstance(IInstance instance, String tag)

Tags an instance with the specified tag string.

This method assigns a tag to the specified instance. Each instance can have only one tag at a time - calling this method with a new tag will replace any existing tag on the instance.

Tags are not case-sensitive. The tag string will be stored and matched in a case-insensitive manner. However, the exact case used when setting the tag may be preserved for display purposes.

To remove a tag from an instance, use an empty string ('') as the tag parameter.

Parameters:

  • instance: The instance to be tagged
  • tag: The tag string to assign. Use '' to remove existing tags.

Returns true if the tag was successfully assigned, or false otherwise.

Inherited from IModel.

Implementation
bool tagInstance(IInstance instance, String tag);

toString() inherited#

String toString()

A string representation of this object.

Some classes have a default textual representation, often paired with a static parse function (like int.parse). These classes will provide the textual representation as their string representation.

Other classes have no meaningful textual representation that a program will care about. Such classes will typically override toString to provide useful information when inspecting the object, mainly for debugging or logging.

Inherited from Object.

Implementation
external String toString();

uninitialize() inherited#

FutureOr<void> uninitialize()

Uninitializes the model, releasing resources. Currently not in use.

Inherited from IModel.

Implementation
FutureOr<void> uninitialize();

updateModelInfo() inherited#

bool updateModelInfo(String name, String tag)

update model info. ModelInfo is derived from model header, the mutable values are: name and tag.

Inherited from IModel.

Implementation
bool updateModelInfo(String name, String tag);

Operators#

operator ==() inherited#

bool operator ==(Object other)

The equality operator.

The default behavior for all Objects is to return true if and only if this object and other are the same object.

Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:

  • Total: It must return a boolean for all arguments. It should never throw.

  • Reflexive: For all objects o, o == o must be true.

  • Symmetric: For all objects o1 and o2, o1 == o2 and o2 == o1 must either both be true, or both be false.

  • Transitive: For all objects o1, o2, and o3, if o1 == o2 and o2 == o3 are true, then o1 == o3 must be true.

The method should also be consistent over time, so whether two objects are equal should only change if at least one of the objects was modified.

If a subclass overrides the equality operator, it should override the hashCode method as well to maintain consistency.

Inherited from Object.

Implementation
external bool operator ==(Object other);