XbimEssentials
XbimEssentials copied to clipboard
Translate cartographic IFC to local coordinates
Hi,
how can I apply a translation of the IFC model ? I have an IFC file with a cartographic coordinates (like 3500000, 2300000) and I would like to translate into a local coordinates (like 0,0,0).
With substraction of minimum coordinate from your model, from all coordinates existing in the model.
@mihalcea-bogdan-daniel do you mean to subtract a deltaX, deltaY for all IIfcCartesianPoint ? If an element is related to another works or the model become corrupted ?
Maybe save in other file name? I didn't give a lot of thought about it.
You can simply subtract a dx and a dy from all cartesian points, but you'll need to do the same for the IfcBuilding/IfcSite instances that contain the solids. Those are also located via a cartesian point. I had this situation when trying to load Civil and Revit exported IFC in the same viwer. They are differently positioned.
The two models above are in the same location. (note that the C3D does not export a site, but only buildings) Revit is using a point with absolute coordinates, and all the cartesian points are relative to that origin. Civil is using 0 and uses absolute coordinates for the cartesian points. These two models will not load properly in xBim unless they use the same origin.
What I did was to 'offset' the C3D model like so:
var cartPoints = model.Instances.OfType<IIfcCartesianPoint>().ToList();
using (var txn = model.BeginTransaction())
{
//#164= IFCCARTESIANPOINT((69830.,208115.,0.));
//update location of the IFCBuilding
var buildings = model.Instances.OfType<IIfcBuilding>().ToList();
List<IIfcCartesianPoint> _siteLoc = new List<IIfcCartesianPoint>();
foreach (var b in buildings)
{
IIfcLocalPlacement placement = b.ObjectPlacement as IIfcLocalPlacement;
if (placement != null)
{
if (placement.RelativePlacement != null)
{
var _3dplace = placement.RelativePlacement as IIfcAxis2Placement3D;
if (_3dplace != null)
{
var pt = _3dplace.Location;
if (pt != null)
{
LogMessage($"Building {b.EntityLabel} placement: {placement.EntityLabel}: {pt.X}, {pt.Y} adjusting...");
pt.Coordinates[0] = 69830;
pt.Coordinates[1] = 208115;
LogMessage($"Building {b.EntityLabel} placement: {placement.EntityLabel}: {pt.X}, {pt.Y} adjusted!");
_siteLoc.Add(pt);
}
}
}
}
else
{
}
}
foreach (var c in cartPoints)
{
if (c.X > 0 && c.Y > 0)
{
if (!_siteLoc.Any(x => x.EntityLabel == c.EntityLabel))
{
c.Coordinates[0] -= 69830;
c.Coordinates[1] -= 208115;
}
}
}
txn.Commit();
}
@dumitrugrl thanks now it's more clear. From IIfcCartesianPoint is it possible to get the object owner ? or there is a way to understand if the IIfcCartesianPoint is relative or absolute coordinate ?