Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please address IFC 4x3 in the documentation — do I need to handle IFC 4x3 and IFC 4.0 separately? #598

Open
wlinna opened this issue Jan 30, 2025 · 2 comments
Labels
awaiting closure Issues that should be closed if we don't hear back on in a week docs

Comments

@wlinna
Copy link

wlinna commented Jan 30, 2025

Right now the examples in documentation say nothing about IFC 4x3. For example, when writing data to an existing IFC file, do I now need to handle all IFC 2x3, IFC4 and IFC 4x3 separately?

Let's take modifying IfcSite as a case study. Below is how I replace the values in an existing IFCSITE entity that. It handles those three versions separately, but I am not sure yet if it is actually necessary for Ifc 4x3 :

var ifcSite = model.Instances.OfType<IIfcSite>().FirstOrDefault()!;

if (model.Header.XbimSchemaVersion == XbimSchemaVersion.Ifc2X3) {
	var ifcSite2x3 = (Xbim.Ifc2x3.ProductExtension.IfcSite) ifcSite;
	if (eastings != null && northings != null) {
		ifcSite2x3.RefLatitude = Xbim.Ifc2x3.MeasureResource.IfcCompoundPlaneAngleMeasure.FromDouble(northings.Value);
		ifcSite2x3.RefLongitude = Xbim.Ifc2x3.MeasureResource.IfcCompoundPlaneAngleMeasure.FromDouble(eastings.Value);
	}
	if (elevation != null) {
		var projectLengthUnit = ((Xbim.Ifc2x3.MeasureResource.IfcUnitAssignment)ifcProject.UnitsInContext).LengthUnit as IIfcSIUnit;
		ifcSite2x3.RefElevation = new Xbim.Ifc2x3.MeasureResource.IfcLengthMeasure(elevation.Value / projectLengthUnit.Power);
	}
} else if (model.Header.XbimSchemaVersion == XbimSchemaVersion.Ifc4) {
	if (eastings != null && northings != null) {
		ifcSite.RefLatitude = Xbim.Ifc4.MeasureResource.IfcCompoundPlaneAngleMeasure.FromDouble(northings.Value);
		ifcSite.RefLongitude = Xbim.Ifc4.MeasureResource.IfcCompoundPlaneAngleMeasure.FromDouble(eastings.Value);
	}
	if (elevation != null) {
		var projectLengthUnit = ((IfcUnitAssignment)ifcProject.UnitsInContext).LengthUnit as IIfcSIUnit;
		ifcSite.RefElevation = new Xbim.Ifc4.MeasureResource.IfcLengthMeasure(elevation.Value / projectLengthUnit!.Power);
	}
} else if (model.Header.XbimSchemaVersion == XbimSchemaVersion.Ifc4x3) {
	var ifcSite4x3 = (Xbim.Ifc4x3.ProductExtension.IfcSite) ifcSite;
	if (eastings != null && northings != null) {
		var latitude = IfcCompoundPlaneAngleMeasure.FromDouble(northings.Value);
		var longitude = IfcCompoundPlaneAngleMeasure.FromDouble(eastings.Value);
		ifcSite4x3.RefLatitude = new Xbim.Ifc4x3.MeasureResource.IfcCompoundPlaneAngleMeasure(latitude);
		ifcSite4x3.RefLongitude = new Xbim.Ifc4x3.MeasureResource.IfcCompoundPlaneAngleMeasure(longitude);
	}
	if (elevation != null) {
		var projectLengthUnit = ((Xbim.Ifc4x3.MeasureResource.IfcUnitAssignment)ifcProject.UnitsInContext).LengthUnit as IIfcSIUnit;
		ifcSite4x3.RefElevation = new Xbim.Ifc4x3.MeasureResource.IfcLengthMeasure(elevation.Value / projectLengthUnit!.Power);
	}
}

(If you are wondering why the code for Ifc4x3 is more complex, it's because Xbim.Ifc4x3.MeasureResource.IfcCompoundPlaneAngleMeasure doesn' have FromDouble method)

@andyward
Copy link
Member

Yes we need to update the docs with some 4x3 examples. On the list. But actually cross-schema support works the same way it does with Ifc4-Ifc2x3. The important thing is that the Ifc4 interfaces are 'special' and work across schemas (Note: in future we'll make this more explicit with a 'Xbim.CrossSchema' that targets the latest schema)

But for now if you use the Ifc4 interfaces all the other schemas implement this contract and handle the cross schema mapping. So setting ifcSite.RefLatitude to an Ifc4.MeasureResource.IfcCompoundPlaneAngleMeasure in the IFC4x3 example below actually assigns an Ifc4x3.MeasureResource.IfcCompoundPlaneAngleMeasure .

Note I've also shown how to use the EntityCreator to create entities agnostic of the schema

// using Xbim.Ifc;
// using Xbim.Ifc4.Interfaces;


double? northings = 50.123d;
double? eastings = -1d;
double? elevation  = 123.4d;

using var model = IfcStore.Open("ViadottoAcerno4x3.ifc");
using var transaction = model.BeginTransaction("Edit");
var ifcSite = model.Instances.OfType<IIfcSite>().FirstOrDefault()!;
var ifcProject = model.Instances.OfType<IIfcProject>().FirstOrDefault()!;

if (eastings != null && northings != null)
{
    ifcSite.RefLatitude = Xbim.Ifc4.MeasureResource.IfcCompoundPlaneAngleMeasure.FromDouble(northings.Value);
    ifcSite.RefLongitude = Xbim.Ifc4.MeasureResource.IfcCompoundPlaneAngleMeasure.FromDouble(eastings.Value);
}

if (elevation != null)
{
    var projectLengthUnit = ifcProject.UnitsInContext.Units.OfType<IIfcSIUnit>().FirstOrDefault(u => u.UnitType == IfcUnitEnum.LENGTHUNIT);
    ifcSite.RefElevation = new Xbim.Ifc4.MeasureResource.IfcLengthMeasure(elevation.Value / (projectLengthUnit?.Power ?? 1d));
}
// Create a Beam in the current schema
var factory = new EntityCreator(model);

var beam = factory.Beam(c => c.PredefinedType = IfcBeamTypeEnum.JOIST);

transaction.Commit();

There are a few items I'll add to the list to follow up on:

  1. We need to complete the IFC4x3 partials = e.g. IfcCompoundPlaneAngleMeasurePartial's AsDouble()
  2. We should consider making some of these partials extension methods on the Cross-schema interfaces. E.g. IfcUnitAssignmentPartial
  3. We need to extend EntityCreator with the new Ifc4x3 entities.

@andyward andyward added the docs label Jan 30, 2025
@wlinna
Copy link
Author

wlinna commented Jan 31, 2025

Thank you for your quick and enlightening comment :)

@andyward andyward added the awaiting closure Issues that should be closed if we don't hear back on in a week label Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting closure Issues that should be closed if we don't hear back on in a week docs
Projects
None yet
Development

No branches or pull requests

2 participants