XbimEssentials icon indicating copy to clipboard operation
XbimEssentials copied to clipboard

Translate cartographic IFC to local coordinates

Open LSE-AP opened this issue 2 years ago • 7 comments

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).

LSE-AP avatar Mar 15 '22 09:03 LSE-AP

With substraction of minimum coordinate from your model, from all coordinates existing in the model.

mihalcea-bogdan-daniel avatar Mar 15 '22 09:03 mihalcea-bogdan-daniel

@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 ?

LSE-AP avatar Mar 15 '22 09:03 LSE-AP

Maybe save in other file name? I didn't give a lot of thought about it.

mihalcea-bogdan-daniel avatar Mar 15 '22 09:03 mihalcea-bogdan-daniel

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.

image

dumitrugrl avatar Mar 15 '22 10:03 dumitrugrl

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.

dumitrugrl avatar Mar 15 '22 10:03 dumitrugrl

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 avatar Mar 15 '22 10:03 dumitrugrl

@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 ?

LSE-AP avatar Mar 15 '22 10:03 LSE-AP