mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 07:09:22 +00:00
feat: Display float properties as string properties for more precision in the patch panel
This change affects the following recipes: `OffsetObjectPlacements`, `OffsetStoreyElevations`, `SetFalseOrigin`, `SetRefElevation` and `SetWorldCoordinateSystem`
This commit is contained in:
committed by
Dion Moult
parent
5572991a7c
commit
8afb1b8b30
@@ -20,10 +20,23 @@ import math
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.placement
|
import ifcopenshell.util.placement
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class Patcher:
|
class Patcher:
|
||||||
def __init__(self, src, file, logger, x=None, y=None, z=None, should_rotate_first=True, ax=None, ay=None, az=None):
|
def __init__(
|
||||||
|
self,
|
||||||
|
src,
|
||||||
|
file,
|
||||||
|
logger,
|
||||||
|
x: typing.Union[str, float] = "0",
|
||||||
|
y: typing.Union[str, float] = "0",
|
||||||
|
z: typing.Union[str, float] = "0",
|
||||||
|
should_rotate_first: bool = True,
|
||||||
|
ax: typing.Optional[typing.Union[str, float]] = "",
|
||||||
|
ay: typing.Optional[typing.Union[str, float]] = "",
|
||||||
|
az: typing.Optional[typing.Union[str, float]] = "",
|
||||||
|
):
|
||||||
"""Offset and rotate all object placements in a model
|
"""Offset and rotate all object placements in a model
|
||||||
|
|
||||||
Every physical object in an IFC model has an object placement, a
|
Every physical object in an IFC model has an object placement, a
|
||||||
@@ -41,11 +54,11 @@ class Patcher:
|
|||||||
entire IFC model.
|
entire IFC model.
|
||||||
|
|
||||||
:param x: The X coordinate to offset by in project length units.
|
:param x: The X coordinate to offset by in project length units.
|
||||||
:type x: float
|
:type x: typing.Union[str, float]
|
||||||
:param y: The Y coordinate to offset by in project length units.
|
:param y: The Y coordinate to offset by in project length units.
|
||||||
:type y: float
|
:type y: typing.Union[str, float]
|
||||||
:param z: The Z coordinate to offset by in project length units.
|
:param z: The Z coordinate to offset by in project length units.
|
||||||
:type z: float
|
:type z: typing.Union[str, float]
|
||||||
:param should_rotate_first: Whether or not to rotate first and then
|
:param should_rotate_first: Whether or not to rotate first and then
|
||||||
translate, or to first translate and rotate afterwards. Defaults to
|
translate, or to first translate and rotate afterwards. Defaults to
|
||||||
rotate first then translate.
|
rotate first then translate.
|
||||||
@@ -55,13 +68,13 @@ class Patcher:
|
|||||||
around the Z axis). If all angle parameters are specified, then it
|
around the Z axis). If all angle parameters are specified, then it
|
||||||
is treated as the angle to rotate around the X axis. Angles are in
|
is treated as the angle to rotate around the X axis. Angles are in
|
||||||
decimal degrees and positive is anticlockwise.
|
decimal degrees and positive is anticlockwise.
|
||||||
:type ax: float,optional
|
:type ax: typing.Union[str, float],optional
|
||||||
:param ay: An optional angle to rotate by for 3D rotations along the Y
|
:param ay: An optional angle to rotate by for 3D rotations along the Y
|
||||||
axis. Angles are in decimal degrees and positive is anticlockwise.
|
axis. Angles are in decimal degrees and positive is anticlockwise.
|
||||||
:type ay: float,optional
|
:type ay: typing.Union[str, float],optional
|
||||||
:param az: An optional angle to rotate by for 3D rotations along the Z
|
:param az: An optional angle to rotate by for 3D rotations along the Z
|
||||||
axis. Angles are in decimal degrees and positive is anticlockwise.
|
axis. Angles are in decimal degrees and positive is anticlockwise.
|
||||||
:type az: float,optional
|
:type az: typing.Union[str, float],optional
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -79,13 +92,21 @@ class Patcher:
|
|||||||
self.src = src
|
self.src = src
|
||||||
self.file = file
|
self.file = file
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.x = x
|
self.x = float(x)
|
||||||
self.y = y
|
self.y = float(y)
|
||||||
self.z = z
|
self.z = float(z)
|
||||||
self.should_rotate_first = should_rotate_first
|
self.should_rotate_first = should_rotate_first
|
||||||
self.ax = ax
|
self.ax = None
|
||||||
self.ay = ay
|
self.ay = None
|
||||||
self.az = az
|
self.az = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.ax = float(ax)
|
||||||
|
self.ay = float(ay)
|
||||||
|
self.az = float(az)
|
||||||
|
except Exception:
|
||||||
|
print("At least one input angle is not specified.")
|
||||||
|
|
||||||
if self.ax is None:
|
if self.ax is None:
|
||||||
self.angle_type = None
|
self.angle_type = None
|
||||||
elif self.ay is None:
|
elif self.ay is None:
|
||||||
|
|||||||
@@ -16,15 +16,17 @@
|
|||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with IfcPatch. If not, see <http://www.gnu.org/licenses/>.
|
# along with IfcPatch. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class Patcher:
|
class Patcher:
|
||||||
def __init__(self, src, file, logger, z=None):
|
def __init__(self, src, file, logger, z: typing.Union[str, float] = "0"):
|
||||||
"""Offset building storeys by a particular Z value
|
"""Offset building storeys by a particular Z value
|
||||||
|
|
||||||
All objects placed relative to the storeys will also be shifted.
|
All objects placed relative to the storeys will also be shifted.
|
||||||
|
|
||||||
:param z: The Z value in project length units to offset storeys by.
|
:param z: The Z value in project length units to offset storeys by.
|
||||||
:type z: float
|
:type z: typing.Union[str, float]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ class Patcher:
|
|||||||
self.src = src
|
self.src = src
|
||||||
self.file = file
|
self.file = file
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.z = z
|
self.z = float(z)
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
project = self.file.by_type("IfcProject")[0]
|
project = self.file.by_type("IfcProject")[0]
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.api.georeference
|
import ifcopenshell.api.georeference
|
||||||
from ifcpatch.recipes import OffsetObjectPlacements, SetWorldCoordinateSystem
|
from ifcpatch.recipes import OffsetObjectPlacements, SetWorldCoordinateSystem
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class Patcher:
|
class Patcher:
|
||||||
@@ -28,14 +29,14 @@ class Patcher:
|
|||||||
file,
|
file,
|
||||||
logger,
|
logger,
|
||||||
name: str = "EPSG:1234",
|
name: str = "EPSG:1234",
|
||||||
x: float = 0,
|
x: typing.Union[str, float] = "0",
|
||||||
y: float = 0,
|
y: typing.Union[str, float] = "0",
|
||||||
z: float = 0,
|
z: typing.Union[str, float] = "0",
|
||||||
e: float = 0,
|
e: typing.Union[str, float] = "0",
|
||||||
n: float = 0,
|
n: typing.Union[str, float] = "0",
|
||||||
h: float = 0,
|
h: typing.Union[str, float] = "0",
|
||||||
gn_angle: float = 0,
|
gn_angle: typing.Union[str, float] = "0",
|
||||||
rotate_angle: float = 0,
|
rotate_angle: typing.Union[str, float] = "0",
|
||||||
):
|
):
|
||||||
"""Sets a false origin with a map conversion in a model
|
"""Sets a false origin with a map conversion in a model
|
||||||
|
|
||||||
@@ -62,14 +63,14 @@ class Patcher:
|
|||||||
self.file = file
|
self.file = file
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.name = name
|
self.name = name
|
||||||
self.x = x
|
self.x = float(x)
|
||||||
self.y = y
|
self.y = float(y)
|
||||||
self.z = z
|
self.z = float(z)
|
||||||
self.e = e
|
self.e = float(e)
|
||||||
self.n = n
|
self.n = float(n)
|
||||||
self.h = h
|
self.h = float(h)
|
||||||
self.gn_angle = gn_angle
|
self.gn_angle = float(gn_angle)
|
||||||
self.rotate_angle = rotate_angle
|
self.rotate_angle = float(rotate_angle)
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
SetWorldCoordinateSystem.Patcher(self.src, self.file, self.logger, x=0, y=0, z=0, ax=0, ay=0, az=0).patch()
|
SetWorldCoordinateSystem.Patcher(self.src, self.file, self.logger, x=0, y=0, z=0, ax=0, ay=0, az=0).patch()
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with IfcPatch. If not, see <http://www.gnu.org/licenses/>.
|
# along with IfcPatch. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class Patcher:
|
class Patcher:
|
||||||
def __init__(self, src, file, logger, elevation=0):
|
def __init__(self, src, file, logger, elevation: typing.Union[str, float] = "0"):
|
||||||
"""Sets the reference elevation of all IfcSites
|
"""Sets the reference elevation of all IfcSites
|
||||||
|
|
||||||
To completely reference model coordinates, a reference elevation should
|
To completely reference model coordinates, a reference elevation should
|
||||||
@@ -30,7 +32,7 @@ class Patcher:
|
|||||||
The reference elevation is simply a numerical attribute.
|
The reference elevation is simply a numerical attribute.
|
||||||
|
|
||||||
:param elevation: The elevation to set.
|
:param elevation: The elevation to set.
|
||||||
:type elevation: float
|
:type elevation: typing.Union[str, float]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -42,7 +44,7 @@ class Patcher:
|
|||||||
self.src = src
|
self.src = src
|
||||||
self.file = file
|
self.file = file
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.elevation = elevation
|
self.elevation = float(elevation)
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
project = self.file.by_type("IfcProject")[0]
|
project = self.file.by_type("IfcProject")[0]
|
||||||
|
|||||||
@@ -18,29 +18,41 @@
|
|||||||
|
|
||||||
import math
|
import math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class Patcher:
|
class Patcher:
|
||||||
def __init__(self, src, file, logger, x=None, y=None, z=None, ax=None, ay=None, az=None):
|
def __init__(
|
||||||
|
self,
|
||||||
|
src,
|
||||||
|
file,
|
||||||
|
logger,
|
||||||
|
x: typing.Union[str, float] = "0",
|
||||||
|
y: typing.Union[str, float] = "0",
|
||||||
|
z: typing.Union[str, float] = "0",
|
||||||
|
ax: typing.Union[str, float] = "0",
|
||||||
|
ay: typing.Union[str, float] = "0",
|
||||||
|
az: typing.Union[str, float] = "0",
|
||||||
|
):
|
||||||
"""Sets the world coordinate system of the geometric representation context
|
"""Sets the world coordinate system of the geometric representation context
|
||||||
|
|
||||||
Sets the world coordinate system to whatever you want.
|
Sets the world coordinate system to whatever you want.
|
||||||
|
|
||||||
:param x: The X coordinate.
|
:param x: The X coordinate.
|
||||||
:type x: float
|
:type x: typing.Union[str, float]
|
||||||
:param y: The Y coordinate.
|
:param y: The Y coordinate.
|
||||||
:type y: float
|
:type y: typing.Union[str, float]
|
||||||
:param z: The Z coordinate.
|
:param z: The Z coordinate.
|
||||||
:type z: float
|
:type z: typing.Union[str, float]
|
||||||
:param ax: An angle to rotate by for 3D rotations along the X axis.
|
:param ax: An angle to rotate by for 3D rotations along the X axis.
|
||||||
Angles are in decimal degrees and positive is anticlockwise.
|
Angles are in decimal degrees and positive is anticlockwise.
|
||||||
:type ax: float
|
:type ax: typing.Union[str, float]
|
||||||
:param ay: An angle to rotate by for 3D rotations along the Y axis.
|
:param ay: An angle to rotate by for 3D rotations along the Y axis.
|
||||||
Angles are in decimal degrees and positive is anticlockwise.
|
Angles are in decimal degrees and positive is anticlockwise.
|
||||||
:type ay: float
|
:type ay: typing.Union[str, float]
|
||||||
:param az: An angle to rotate by for 3D rotations along the Z axis.
|
:param az: An angle to rotate by for 3D rotations along the Z axis.
|
||||||
Angles are in decimal degrees and positive is anticlockwise.
|
Angles are in decimal degrees and positive is anticlockwise.
|
||||||
:type az: float
|
:type az: typing.Union[str, float]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -52,17 +64,17 @@ class Patcher:
|
|||||||
self.src = src
|
self.src = src
|
||||||
self.file = file
|
self.file = file
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.x = x
|
self.x = float(x)
|
||||||
self.y = y
|
self.y = float(y)
|
||||||
self.z = z
|
self.z = float(z)
|
||||||
self.ax = ax
|
self.ax = float(ax)
|
||||||
self.ay = ay
|
self.ay = float(ay)
|
||||||
self.az = az
|
self.az = float(az)
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
rotate = self.identity_matrix()
|
rotate = self.identity_matrix()
|
||||||
|
|
||||||
for arg in (("x", float(self.ax)), ("y", float(self.ay)), ("z", float(self.az))):
|
for arg in (("x", self.ax), ("y", self.ay), ("z", self.az)):
|
||||||
if arg[1]:
|
if arg[1]:
|
||||||
rotate = getattr(self, f"{arg[0]}_rotation_matrix")(math.radians(arg[1]), rotate)
|
rotate = getattr(self, f"{arg[0]}_rotation_matrix")(math.radians(arg[1]), rotate)
|
||||||
|
|
||||||
@@ -74,13 +86,13 @@ class Patcher:
|
|||||||
for context in self.file.by_type("IfcGeometricRepresentationContext", include_subtypes=False):
|
for context in self.file.by_type("IfcGeometricRepresentationContext", include_subtypes=False):
|
||||||
if context.ContextType == "Model":
|
if context.ContextType == "Model":
|
||||||
context.WorldCoordinateSystem = self.file.createIfcAxis2Placement3D(
|
context.WorldCoordinateSystem = self.file.createIfcAxis2Placement3D(
|
||||||
self.file.createIfcCartesianPoint((float(self.x), float(self.y), float(self.z))),
|
self.file.createIfcCartesianPoint((self.x, self.y, self.z)),
|
||||||
self.file.createIfcDirection(z.tolist()),
|
self.file.createIfcDirection(z.tolist()),
|
||||||
self.file.createIfcDirection(x.tolist()),
|
self.file.createIfcDirection(x.tolist()),
|
||||||
)
|
)
|
||||||
elif context.ContextType == "Plan":
|
elif context.ContextType == "Plan":
|
||||||
context.WorldCoordinateSystem = self.file.createIfcAxis2Placement2D(
|
context.WorldCoordinateSystem = self.file.createIfcAxis2Placement2D(
|
||||||
self.file.createIfcCartesianPoint((float(self.x), float(self.y), float(self.z))),
|
self.file.createIfcCartesianPoint((self.x, self.y, self.z)),
|
||||||
self.file.createIfcDirection(x.tolist()),
|
self.file.createIfcDirection(x.tolist()),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user