Fix bug in SetFalseOrigin which incorrectly handled z height and also add ability to handle non-mapconversion based transformations.

I can't believe I accidentally left out the minus sign. The ability to
handle simple remapping of location A --> B is useful for software that
doesn't support map conversion properly.
This commit is contained in:
Dion Moult
2025-01-28 17:33:15 +11:00
parent 03bfd828e2
commit 693244e20e
@@ -37,16 +37,29 @@ class Patcher:
gn_angle: typing.Union[str, float] = "0", gn_angle: typing.Union[str, float] = "0",
rotate_angle: typing.Union[str, float] = "0", rotate_angle: typing.Union[str, float] = "0",
): ):
"""Sets a false origin with a map conversion in a model """Sets local coordinates XYZ as a (false) origin that correlates to map coordinates ENH
The recommended workflow is to specify a projected CRS name (e.g.
EPSG:1234). The local XYZ coordinate will become the new local origin
in IFC (we call this the false origin). A map conversion will be added
that correlates that origin to eastings, northings, and orthogonal
height.
On IFC2X3 models, a EPset_MapConversion is used. On IFC2X3 models, a EPset_MapConversion is used.
:param x: The local X coordinate which will become the new false origin. If the map projected CRS name is left blank, it merely transforms the
:param y: The local Y coordinate which will become the new false origin. model such that the current point XYZ now becomes the point ENH (still
:param z: The local Z coordinate which will become the new false origin. in local coordinates). The Grid North angle is ignored. Any existing
:param e: The easting which the false origin correlates to. georeferencing is purged. This workflow not recommended, but may be is
:param n: The northing which the false origin correlates to. relevant for BIM software that does not properly support map
:param h: The height which the false origin correlates to. coordinates.
:param x: The local X coordinate in project units which will become the new false origin.
:param y: The local Y coordinate in project units which will become the new false origin.
:param z: The local Z coordinate in project units which will become the new false origin.
:param e: The easting in project units which the false origin correlates to.
:param n: The northing in project units which the false origin correlates to.
:param h: The height in project units which the false origin correlates to.
:param gn_angle: The anticlockwise angle to grid north. :param gn_angle: The anticlockwise angle to grid north.
:param rotate_angle: An anticlockwise angle to rotate the model by if :param rotate_angle: An anticlockwise angle to rotate the model by if
necessary (pivoted by the false origin). necessary (pivoted by the false origin).
@@ -72,6 +85,7 @@ class Patcher:
def patch(self): def patch(self):
SetWorldCoordinateSystem.Patcher(self.file, self.logger, x=0, y=0, z=0, ax=0, ay=0, az=0).patch() SetWorldCoordinateSystem.Patcher(self.file, self.logger, x=0, y=0, z=0, ax=0, ay=0, az=0).patch()
if self.name:
coordinate_operation = { coordinate_operation = {
"Eastings": self.e, "Eastings": self.e,
"Northings": self.n, "Northings": self.n,
@@ -85,14 +99,33 @@ class Patcher:
ifc_class = "IfcMapConversion" ifc_class = "IfcMapConversion"
ifcopenshell.api.georeference.add_georeferencing(self.file, ifc_class=ifc_class) ifcopenshell.api.georeference.add_georeferencing(self.file, ifc_class=ifc_class)
ifcopenshell.api.georeference.edit_georeferencing( ifcopenshell.api.georeference.edit_georeferencing(
self.file, projected_crs={"Name": self.name}, coordinate_operation=coordinate_operation self.file, projected_crs={"Name": self.name, "MapUnit": None}, coordinate_operation=coordinate_operation
) )
OffsetObjectPlacements.Patcher( OffsetObjectPlacements.Patcher(
self.file, self.file,
self.logger, self.logger,
x=-self.x, x=-self.x,
y=-self.y, y=-self.y,
z=self.z, z=-self.z,
should_rotate_first=False, should_rotate_first=False,
ax=self.rotate_angle or None, ax=self.rotate_angle or None,
).patch() ).patch()
else:
ifcopenshell.api.georeference.remove_georeferencing(self.file)
OffsetObjectPlacements.Patcher(
self.file,
self.logger,
x=-self.x,
y=-self.y,
z=-self.z,
should_rotate_first=False,
ax=self.rotate_angle or None,
).patch()
OffsetObjectPlacements.Patcher(
self.file,
self.logger,
x=self.e,
y=self.n,
z=self.h,
should_rotate_first=False,
).patch()