diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_profile_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_profile_representation.py
index 36b0cc5254..fca7f9e38c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_profile_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_profile_representation.py
@@ -18,7 +18,7 @@
import ifcopenshell.geom
import ifcopenshell.util.unit
-from ifcopenshell.util.representation import ClippingInfo
+from ifcopenshell.util.shape_builder import ClippingInfo
class Usecase:
diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
index 14e4ee2268..4c0488ea7c 100644
--- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_wall_representation.py
@@ -18,7 +18,7 @@
import ifcopenshell.util.unit
from math import sin, cos
-from ifcopenshell.util.representation import ClippingInfo
+from ifcopenshell.util.shape_builder import ClippingInfo
class Usecase:
diff --git a/src/ifcopenshell-python/ifcopenshell/util/representation.py b/src/ifcopenshell-python/ifcopenshell/util/representation.py
index 380e4dc825..68842d3ef3 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/representation.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/representation.py
@@ -16,13 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
-from __future__ import annotations
import numpy as np
import ifcopenshell
-import ifcopenshell.util.shape_builder
-from mathutils import Vector
-from typing import Any, Union
-from dataclasses import dataclass
def get_context(ifc_file, context, subcontext=None, target_view=None):
@@ -91,50 +86,3 @@ def resolve_items(representation, matrix=None):
else:
results.append({"matrix": matrix.copy(), "item": item})
return results
-
-
-@dataclass
-class ClippingInfo:
- location: tuple[float, float, float]
- normal: tuple[float, float, float]
- type: str = "IfcBooleanClippingResult"
- operand_type: str = "IfcHalfSpaceSolid"
-
- @classmethod
- def parse(cls, raw_data: Any) -> Union[ifcopenshell.entity_instance, ClippingInfo, None]:
- """`raw_data` can be either:
- - IfcBooleanResult IFC entity
- - `ClippingInfo` instance
- - dictionary to define `ClippingInfo` - either `location` and `normal`
- or a `matrix` where XY plane is the clipping boundary and +Z is removed.
- `matrix` method will be soon to be deprecated completely.
- """
- if isinstance(raw_data, ifcopenshell.entity_instance):
- if not raw_data.is_a("IfcBooleanResult"):
- raise Exception(f"Provided clipping of unexpected IFC class: {raw_data}")
- return raw_data
- elif isinstance(raw_data, ClippingInfo):
- return raw_data
- elif isinstance(raw_data, dict):
- if "matrix" in raw_data:
- raw_data = raw_data.copy()
- matrix = np.array(raw_data["matrix"])[:3]
- raw_data["normal"] = matrix[:, 2].tolist()
- raw_data["location"] = matrix[:, 3].tolist()
- del raw_data["matrix"]
- clipping_data = cls(**raw_data)
- if clipping_data.type != "IfcBooleanClippingResult":
- raise Exception(f'Provided clipping with unexpected result type "{clipping_data.type}"')
- if clipping_data.operand_type != "IfcHalfSpaceSolid":
- raise Exception(f'Provided clipping with unexpected operand type "{clipping_data.operand_type}"')
- return clipping_data
- raise Exception(f"Unexpected clipping type provided: {raw_data}")
-
- def apply(
- self, file: ifcopenshell.file, first_operand: ifcopenshell.entity_instance, unit_scale: float
- ) -> ifcopenshell.entity_instance:
- builder = ifcopenshell.util.shape_builder.ShapeBuilder(file)
- plane = builder.plane(location=Vector([i / unit_scale for i in self.location]), normal=Vector(self.normal))
- second_operand = file.createIfcHalfSpaceSolid(plane, False)
- first_operand = file.createIfcBooleanClippingResult("DIFFERENCE", first_operand, second_operand)
- return first_operand
diff --git a/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py b/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
index d1782272f1..bbcd8e6f60 100644
--- a/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
+++ b/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py
@@ -16,13 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see .
+from __future__ import annotations
+import numpy as np
import collections
import ifcopenshell
import ifcopenshell.api
from math import cos, sin, pi, tan, radians, degrees, atan, sqrt, ceil
-from mathutils import Vector, Matrix
+from typing import List, Any, Union
from itertools import chain
-from typing import List
+from mathutils import Vector, Matrix
+from dataclasses import dataclass
V = lambda *x: Vector([float(i) for i in x])
sign = lambda x: x and (1, -1)[x < 0]
@@ -1473,3 +1476,50 @@ class ShapeBuilder:
"main_profile_dimension": profile_dim[lateral_axis],
}
return rep, bend_data
+
+
+@dataclass
+class ClippingInfo:
+ location: tuple[float, float, float]
+ normal: tuple[float, float, float]
+ type: str = "IfcBooleanClippingResult"
+ operand_type: str = "IfcHalfSpaceSolid"
+
+ @classmethod
+ def parse(cls, raw_data: Any) -> Union[ifcopenshell.entity_instance, ClippingInfo, None]:
+ """`raw_data` can be either:
+ - IfcBooleanResult IFC entity
+ - `ClippingInfo` instance
+ - dictionary to define `ClippingInfo` - either `location` and `normal`
+ or a `matrix` where XY plane is the clipping boundary and +Z is removed.
+ `matrix` method will be soon to be deprecated completely.
+ """
+ if isinstance(raw_data, ifcopenshell.entity_instance):
+ if not raw_data.is_a("IfcBooleanResult"):
+ raise Exception(f"Provided clipping of unexpected IFC class: {raw_data}")
+ return raw_data
+ elif isinstance(raw_data, ClippingInfo):
+ return raw_data
+ elif isinstance(raw_data, dict):
+ if "matrix" in raw_data:
+ raw_data = raw_data.copy()
+ matrix = np.array(raw_data["matrix"])[:3]
+ raw_data["normal"] = matrix[:, 2].tolist()
+ raw_data["location"] = matrix[:, 3].tolist()
+ del raw_data["matrix"]
+ clipping_data = cls(**raw_data)
+ if clipping_data.type != "IfcBooleanClippingResult":
+ raise Exception(f'Provided clipping with unexpected result type "{clipping_data.type}"')
+ if clipping_data.operand_type != "IfcHalfSpaceSolid":
+ raise Exception(f'Provided clipping with unexpected operand type "{clipping_data.operand_type}"')
+ return clipping_data
+ raise Exception(f"Unexpected clipping type provided: {raw_data}")
+
+ def apply(
+ self, file: ifcopenshell.file, first_operand: ifcopenshell.entity_instance, unit_scale: float
+ ) -> ifcopenshell.entity_instance:
+ builder = ShapeBuilder(file)
+ plane = builder.plane(location=Vector([i / unit_scale for i in self.location]), normal=Vector(self.normal))
+ second_operand = file.createIfcHalfSpaceSolid(plane, False)
+ first_operand = file.createIfcBooleanClippingResult("DIFFERENCE", first_operand, second_operand)
+ return first_operand