Skip to content

Commit

Permalink
extended helper function to support cross schema creation
Browse files Browse the repository at this point in the history
  • Loading branch information
WalchAndreas committed Feb 14, 2025
1 parent 7bd5b3b commit a4aa419
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 88 deletions.
3 changes: 3 additions & 0 deletions src/Aardvark.Data.Ifc/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### 1.1.0-prerelease0008
- Refactored to support cross schema creation

### 1.1.0-prerelease0007
- Updated xBIM-Essentials to resolve reported bug and added IfcLightingFixture Extensions

Expand Down
10 changes: 5 additions & 5 deletions src/Aardvark.Data.Ifc/XbimExtensions/GeneralExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

using Xbim.Common;
using Xbim.Ifc4.Interfaces;
using Xbim.Ifc4.Kernel;
using Xbim.Ifc4.ProductExtension;
using Xbim.Ifc;
using Xbim.Common.ExpressValidation;
using Xbim.Common.Enumerations;
Expand All @@ -28,6 +26,7 @@ public static class GeneralExt
public static T New<T>(this IModel model, Action<T> func) where T : IInstantiableEntity
{
// Convenient function to directly create entities from model
// TODO...should not be used -> use model.Factory to guarantee ifc-schema independent creation!
return model.Instances.New(func);
}

Expand Down Expand Up @@ -81,9 +80,10 @@ public static void CreateMinimalProject(this IfcStore model, ProjectUnitsExtende
{
using var txnInit = model.BeginTransaction("Init Project");
// there should always be one project in the model
var project = model.New<IfcProject>(p => p.Name = projectName);
var project = model.Factory().Project(p => p.Name = projectName);

// our shortcut to define basic default units

var xBimDefaultUnits = units switch
{
ProjectUnitsExtended.ImperialUnits => ProjectUnits.ImperialUnits,
Expand All @@ -102,7 +102,7 @@ public static void CreateMinimalProject(this IfcStore model, ProjectUnitsExtende
};

// add site
var site = model.New<IfcSite>(w => w.Name = siteName);
var site = model.Factory().Site(w => w.Name = siteName);
project.AddSite(site);

txnInit.Commit();
Expand Down
30 changes: 25 additions & 5 deletions src/Aardvark.Data.Ifc/XbimExtensions/Ifc4x3Ext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Linq;
using Xbim.Ifc4.Interfaces;
using Xbim.Ifc4x3.Kernel;
using Xbim.Ifc4x3.ProductExtension;
Expand All @@ -9,6 +8,8 @@ namespace Aardvark.Data.Ifc
{
public static class Ifc4x3Ext
{
#region Xbim.Ifc4x3.Kernel.IfcObject

public static IfcRelDefinesByType AddDefiningType(this IfcObject obj, IfcTypeObject theType)
{
var typedefs = obj.Model.Instances.Where<IfcRelDefinesByType>(r => r.RelatingType == theType).ToList();
Expand All @@ -28,11 +29,9 @@ public static IfcRelDefinesByType AddDefiningType(this IfcObject obj, IfcTypeObj

public static void AddPropertySet(this IfcObject obj, IfcPropertySet pSet)
{

var relDef = obj.Model.Instances.OfType<IfcRelDefinesByProperties>().FirstOrDefault(r => pSet.Equals(r.RelatingPropertyDefinition));
if (relDef == null)
{

relDef = obj.Model.Instances.New<IfcRelDefinesByProperties>();
relDef.RelatingPropertyDefinition = pSet;
}
Expand All @@ -45,7 +44,7 @@ public static IfcElementQuantity GetElementQuantity(this IfcObject obj, string p
return qSets.FirstOrDefault(qset => string.Compare(pSetName, qset.Name, !caseSensitive) == 0);
}

public static IIfcElementQuantity AddQuantity(this IfcObject obj, string propertySetName, IfcPhysicalQuantity quantity, string methodOfMeasurement = null)
public static IfcElementQuantity AddQuantity(this IfcObject obj, string propertySetName, IfcPhysicalQuantity quantity, string methodOfMeasurement = null)
{
var pset = obj.GetElementQuantity(propertySetName);

Expand All @@ -61,5 +60,26 @@ public static IIfcElementQuantity AddQuantity(this IfcObject obj, string propert
if (!string.IsNullOrEmpty(methodOfMeasurement)) pset.MethodOfMeasurement = methodOfMeasurement;
return pset;
}

#endregion

#region IfcProject

public static void AddSite(this IfcProject proj, IfcSite site)
{
var decomposition = proj.IsDecomposedBy.FirstOrDefault();
if (decomposition == null) //none defined create the relationship
{
var relSub = proj.Model.New<IfcRelAggregates>(relSub =>
{
relSub.RelatingObject = proj;
relSub.RelatedObjects.Add(site);
});
}
else
decomposition.RelatedObjects.Add(site);
}

#endregion
}
}
33 changes: 33 additions & 0 deletions src/Aardvark.Data.Ifc/XbimExtensions/InterfaceExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,38 @@ public static void AddElement(this IIfcSpatialStructureElement spat, IIfcProduct
else
spatialStructure.RelatedElements.Add(product);
}

public static void AddSite(this IIfcProject proj, IIfcSite site)
{
switch (proj, site)
{
case (Xbim.Ifc2x3.Kernel.IfcProject p, Xbim.Ifc2x3.ProductExtension.IfcSite s):
p.AddSite(s); break;
case (Xbim.Ifc4.Kernel.IfcProject p, Xbim.Ifc4.ProductExtension.IfcSite s):
p.AddSite(s); break;
case (Xbim.Ifc4x3.Kernel.IfcProject p, Xbim.Ifc4x3.ProductExtension.IfcSite s):
p.AddSite(s); break;
default: throw new NotSupportedException($"Schema {proj.Model.SchemaVersion} does not provide AddPropertySet or mixed obj and typeobject!");
};
}

public static void SetOrChangeSiUnit(this IIfcUnitAssignment ua, IfcUnitEnum unitType, IfcSIUnitName siUnitName, IfcSIPrefix? siUnitPrefix)
{
var si = ua.Units.OfType<IIfcSIUnit>().FirstOrDefault(u => u.UnitType == unitType);
if (si != null)
{
si.Prefix = siUnitPrefix;
si.Name = siUnitName;
}
else
{
ua.Units.Add(ua.Model.Factory().SIUnit(s =>
{
s.UnitType = unitType;
s.Name = siUnitName;
s.Prefix = siUnitPrefix;
}));
}
}
}
}
22 changes: 16 additions & 6 deletions src/Aardvark.Data.Ifc/XbimExtensions/LightExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,33 @@ namespace Aardvark.Data.Ifc
{
public static class IfcLightingExtensions
{
public static IfcLightFixtureType CreateLightType(this IModel model, IfcLightFixtureTypeEnum lightType, IEnumerable<IIfcRepresentationMap> repMaps, IEnumerable<IIfcPropertySetDefinition> properties, string name = "")
public static IIfcLightFixtureType CreateLightType(this IModel model, IfcLightFixtureTypeEnum lightType, IEnumerable<IIfcRepresentationMap> repMaps, IEnumerable<IIfcPropertySetDefinition> properties, string name = "")
{
var proxy = ProductExt.CreateTypeProduct<IfcLightFixtureType>(model, repMaps, properties, name);
proxy.PredefinedType = lightType;
var proxy = model.Factory().LightFixtureType(p =>
{
p.PredefinedType = lightType;
p.Name = name;
});
proxy.AttachGeometriesAndProperties(repMaps, properties);
return proxy;
}

public static IIfcLightFixture Instantiate(this IfcLightFixtureType lightType, string name, IIfcObjectPlacement placement, Trafo3d trafo, IfcLightFixtureTypeEnum? ltenum = null)
public static IIfcLightFixture Instantiate(this IIfcLightFixtureType lightType, string name, IIfcObjectPlacement placement, Trafo3d trafo, IfcLightFixtureTypeEnum? ltenum = null)
{
var instance = ProductExt.Instantiate<IfcLightFixtureType, IfcLightFixture>(lightType, name, placement, trafo);
var light = lightType.Model.New<IfcLightFixture>(l => l.Name = name); // TODO <- ifcLightFixture is currently not available in EntityCreation

var instance = (IIfcLightFixture) light.CreateAttachInstancedRepresentation(lightType, placement, trafo);

if (lightType.PredefinedType != IfcLightFixtureTypeEnum.NOTDEFINED && ltenum.HasValue) instance.PredefinedType = ltenum;
return instance;
}

public static IIfcLightFixture Instantiate(this IfcLightFixtureType lightType, string name, IIfcObjectPlacement placement, Dictionary<IIfcRepresentationMap, Trafo3d> trafos, IfcLightFixtureTypeEnum? ltenum = null)
{
var instance = ProductExt.Instantiate<IfcLightFixtureType, IfcLightFixture>(lightType, name, placement, trafos);
var light = lightType.Model.New<IfcLightFixture>(l => l.Name = name); // TODO <- ifcLightFixture is currently not available in EntityCreation

var instance = (IIfcLightFixture) light.CreateAttachInstancedRepresentation(lightType, placement, trafos);

if (lightType.PredefinedType != IfcLightFixtureTypeEnum.NOTDEFINED && ltenum.HasValue) instance.PredefinedType = ltenum;
return instance;
}
Expand Down
101 changes: 37 additions & 64 deletions src/Aardvark.Data.Ifc/XbimExtensions/ProductExt.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Aardvark.Base;
using Aardvark.Geometry;

using Xbim.Common;
using Xbim.Ifc4.Interfaces;
using Xbim.Ifc4.SharedBldgElements;

namespace Aardvark.Data.Ifc
{
public static class ProductExt
{
public static T CreateTypeProduct<T>(this IModel model, IEnumerable<IIfcRepresentationMap> repMaps, IEnumerable<IIfcPropertySetDefinition> properties, string name = "") where T : IIfcTypeProduct, IInstantiableEntity
public static void AttachGeometriesAndProperties(this IIfcTypeProduct product, IEnumerable<IIfcRepresentationMap> repMaps, IEnumerable<IIfcPropertySetDefinition> properties)
{
return model.New<T>(l =>
{
//l.PredefinedType; // Has to be set afterwards!
l.Name = name;
if (!repMaps.IsEmptyOrNull()) l.RepresentationMaps.AddRange(repMaps); // shared geometries
if (!properties.IsEmptyOrNull()) l.HasPropertySets.AddRange(properties); // shared properties
});
if (!repMaps.IsEmptyOrNull()) product.RepresentationMaps.AddRange(repMaps); // attach shared geometries
if (!properties.IsEmptyOrNull()) product.HasPropertySets.AddRange(properties); // attach shared properties
}

public static IfcBuildingElementProxyType CreateProxyType(this IModel model, IfcBuildingElementProxyTypeEnum proxyType, IEnumerable<IIfcRepresentationMap> repMaps, IEnumerable<IIfcPropertySetDefinition> properties, string name = "")
public static IIfcBuildingElementProxyType CreateProxyType(this IModel model, IfcBuildingElementProxyTypeEnum proxyType, IEnumerable<IIfcRepresentationMap> repMaps, IEnumerable<IIfcPropertySetDefinition> properties, string name = "")
{
var proxy = CreateTypeProduct<IfcBuildingElementProxyType>(model, repMaps, properties, name);
proxy.PredefinedType = proxyType;
var proxy = model.Factory().BuildingElementProxyType(p =>
{
p.PredefinedType = proxyType;
p.Name = name;
});
proxy.AttachGeometriesAndProperties(repMaps, properties);
return proxy;
}

Expand All @@ -36,72 +33,48 @@ public static T LinkToType<T>(this T obj, IIfcTypeObject objType) where T : IIfc
return obj;
}

public static I Instantiate<T, I>(this T objectType, string name, IIfcObjectPlacement placement, Trafo3d trafo) where T : IIfcElementType where I : IIfcProduct, IInstantiableEntity
public static IIfcProduct CreateAttachInstancedRepresentation(this IIfcProduct product, IIfcElementType objectType, IIfcObjectPlacement placement, Trafo3d trafo)
{
var factory = objectType.Model.Factory();
// create instance and transform all representations by global trafo
var instance = objectType.Model.New<I>(t =>
{
t.Name = name;
t.ObjectPlacement = placement;
t.Representation = factory.ProductDefinitionShape(r =>
t.Representation = factory.ProductDefinitionShape(r =>
r.Representations.AddRange(objectType.RepresentationMaps.Select(m => m.Instantiate(trafo)))));
});
var shapes = objectType.RepresentationMaps.Select(m =>
m.Instantiate(trafo));

// attach instanced representation (transformed by global trafo)
product.ObjectPlacement = placement;
product.Representation = objectType.Model.Factory().ProductDefinitionShape(r => r.Representations.AddRange(shapes));

return instance.LinkToType(objectType);
return product.LinkToType(objectType);
}

public static I Instantiate<T, I>(this T objectType, string name, IIfcObjectPlacement placement, Dictionary<IIfcRepresentationMap, Trafo3d> trafos) where T : IIfcElementType where I : IIfcProduct, IInstantiableEntity
public static IIfcProduct CreateAttachInstancedRepresentation(this IIfcProduct product, IIfcElementType objectType, IIfcObjectPlacement placement, Dictionary<IIfcRepresentationMap, Trafo3d> trafos)
{
var factory = objectType.Model.Factory();
// create instance and transform indevidual representations
var instance = objectType.Model.New<I>(t =>
{
t.Name = name;
t.ObjectPlacement = placement;
t.Representation = factory.ProductDefinitionShape(r =>
r.Representations.AddRange(objectType.RepresentationMaps.Select(m =>
trafos.TryGetValue(m, out Trafo3d trafo) ? m.Instantiate(trafo) : m.Instantiate(Trafo3d.Identity))));
});
var shapes = objectType.RepresentationMaps.Select(m =>
trafos.TryGetValue(m, out Trafo3d trafo) ? m.Instantiate(trafo) : m.Instantiate(Trafo3d.Identity));

return instance.LinkToType(objectType);
// attach instanced representation (transformed by indevidual trafos)
product.ObjectPlacement = placement;
product.Representation = objectType.Model.Factory().ProductDefinitionShape(r => r.Representations.AddRange(shapes));

return product.LinkToType(objectType);
}

public static T CreateElement<T>(this IModel model, string elementName, IIfcObjectPlacement placement, PolyMesh mesh, C4d? fallbackColor, IIfcSurfaceStyle surfaceStyle = null, IIfcPresentationLayerAssignment layer = null, bool triangulated = true) where T : IIfcProduct, IInstantiableEntity
public static IIfcProduct CreateAttachRepresentation(this IIfcProduct product, IIfcObjectPlacement placement, PolyMesh mesh, C4d? fallbackColor, IIfcSurfaceStyle surfaceStyle = null, IIfcPresentationLayerAssignment layer = null, bool triangulated = true)
{
// create a Definition shape to hold the geometry
var shape = model.CreateShapeRepresentationTessellationStyled(mesh, fallbackColor, surfaceStyle, layer, triangulated);

return model.New<T>(c => {
c.Name = elementName;
var shape = product.Model.CreateShapeRepresentationTessellationStyled(mesh, fallbackColor, surfaceStyle, layer, triangulated);

// create a Product Definition and add the model geometry to the cube
c.Representation = model.Factory().ProductDefinitionShape(r => r.Representations.Add(shape));
// attached creaded shapes
product.ObjectPlacement = placement;
product.Representation = product.Model.Factory().ProductDefinitionShape(r => r.Representations.Add(shape));

// now place the object into the model
c.ObjectPlacement = placement;
});
return product;
}

public static T CreateElement<T>(this IModel model, string elementName, V3d position, PolyMesh mesh, C4d? fallbackColor = null, IIfcSurfaceStyle surfaceStyle = null, IIfcPresentationLayerAssignment layer = null, bool triangulated = true) where T : IIfcProduct, IInstantiableEntity
public static IIfcProduct CreateAttachRepresentation(this IIfcProduct product, V3d position, PolyMesh mesh, C4d? fallbackColor = null, IIfcSurfaceStyle surfaceStyle = null, IIfcPresentationLayerAssignment layer = null, bool triangulated = true)
{
var placement = model.CreateLocalPlacement(position);
return model.CreateElement<T>(elementName, placement, mesh, fallbackColor, surfaceStyle, layer, triangulated);
}
var placement = product.Model.CreateLocalPlacement(position);
product.CreateAttachRepresentation(placement, mesh, fallbackColor, surfaceStyle, layer, triangulated);

public static T CreateAttachElement<T>(this IIfcSpatialStructureElement parent, string elementName, IIfcObjectPlacement placement, PolyMesh mesh, C4d? fallbackColor = null, IIfcSurfaceStyle surfaceStyle = null, IIfcPresentationLayerAssignment layer = null, bool triangulated = true) where T : IIfcProduct, IInstantiableEntity
{
var element = parent.Model.CreateElement<T>(elementName, placement, mesh, fallbackColor, surfaceStyle, layer, triangulated);
parent.AddElement(element);
return element;
}

public static T CreateAttachElement<T>(this IIfcSpatialStructureElement parent, string elementName, V3d position, PolyMesh mesh, C4d? fallbackColor = null, IIfcSurfaceStyle surfaceStyle = null, IIfcPresentationLayerAssignment layer = null, bool triangulated = true) where T : IIfcProduct, IInstantiableEntity
{
var element = parent.Model.CreateElement<T>(elementName, position, mesh, fallbackColor, surfaceStyle, layer, triangulated);
parent.AddElement(element);
return element;
return product;
}
}
}
Loading

0 comments on commit a4aa419

Please sign in to comment.