Skip to content

Commit 3e4d0f5

Browse files
committed
Adds volume and surface area properties
Adds `volume` and `surface_area` properties to the `TessellatedBrep` class. These properties calculate the volume and surface area of closed meshes using COMPAS geometry functions. This allows to easily extract geometrical properties from tessellated representations.
1 parent 0a1318e commit 3e4d0f5

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
* Added `volume` property to `TessellatedBrep` class for calculating volume of closed meshes using COMPAS geometry functions
13+
* Added `surface_area` property to `TessellatedBrep` class for calculating surface area by summing face areas
14+
1215
### Changed
1316

1417
### Removed

scripts/7.1_geometry_ops.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from compas_ifc.model import Model
2+
3+
model = Model("data/wall-with-opening-and-window.ifc")
4+
model.print_summary()
5+
6+
unit = model.unit
7+
8+
element = model.get_entities_by_type("IfcWindow")[0]
9+
print("Volume:", element.geometry.volume, unit + "³")
10+
print("Surface Area:", element.geometry.surface_area, unit + "²")

src/compas_ifc/brep/tessellatedbrep.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import numpy as np
22
from compas.datastructures import Mesh
33
from compas.geometry import Geometry
4+
from compas.geometry import area_polygon
45
from compas.geometry import bounding_box
56
from compas.geometry import transform_points_numpy
7+
from compas.geometry import volume_polyhedron
68

79

810
class TessellatedBrep(Geometry):
@@ -41,3 +43,65 @@ def obb(self):
4143
from compas.geometry import oriented_bounding_box_numpy
4244

4345
return Box.from_bounding_box(oriented_bounding_box_numpy(self.vertices))
46+
47+
@property
48+
def volume(self):
49+
"""Calculate the volume of the tessellated BREP by converting to mesh.
50+
51+
Returns
52+
-------
53+
float or None
54+
The volume of the BREP if the mesh is closed, None otherwise.
55+
"""
56+
# Handle edge case: empty vertices or faces
57+
if len(self.vertices) == 0 or len(self.faces) == 0:
58+
return None
59+
60+
try:
61+
mesh = self.to_mesh()
62+
63+
# Check if mesh is closed - volume can only be calculated for closed meshes
64+
if not mesh.is_closed():
65+
return None
66+
67+
# Get vertices and faces for volume calculation
68+
vertices, faces = mesh.to_vertices_and_faces()
69+
70+
# Calculate volume using COMPAS geometry function
71+
return volume_polyhedron((vertices, faces))
72+
73+
except Exception:
74+
# Return None if any error occurs during calculation
75+
return None
76+
77+
@property
78+
def surface_area(self):
79+
"""Calculate the surface area of the tessellated BREP by converting to mesh.
80+
81+
Returns
82+
-------
83+
float or None
84+
The surface area of the BREP, or None if calculation fails.
85+
"""
86+
# Handle edge case: empty vertices or faces
87+
if len(self.vertices) == 0 or len(self.faces) == 0:
88+
return None
89+
90+
try:
91+
mesh = self.to_mesh()
92+
93+
# Calculate total surface area by summing face areas
94+
total_area = 0.0
95+
for face_key in mesh.faces():
96+
# Get face vertices coordinates
97+
face_vertices = [mesh.vertex_coordinates(vertex) for vertex in mesh.face_vertices(face_key)]
98+
99+
# Calculate area of this face using COMPAS geometry function
100+
face_area = area_polygon(face_vertices)
101+
total_area += face_area
102+
103+
return total_area
104+
105+
except Exception:
106+
# Return None if any error occurs during calculation
107+
return None

0 commit comments

Comments
 (0)