mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 12:57:57 +00:00
More robust footprint area calculation with support for IfcSpace floor area
This commit is contained in:
@@ -20,7 +20,7 @@ class QtoCalculator():
|
|||||||
elif 'perimeter' in prop_name:
|
elif 'perimeter' in prop_name:
|
||||||
return self.get_perimeter(obj)
|
return self.get_perimeter(obj)
|
||||||
elif 'area' in prop_name \
|
elif 'area' in prop_name \
|
||||||
and ('footprint' in prop_name or 'section' in prop_name):
|
and ('footprint' in prop_name or 'section' in prop_name or 'floor' in prop_name):
|
||||||
return self.get_footprint_area(obj)
|
return self.get_footprint_area(obj)
|
||||||
elif 'area' in prop_name \
|
elif 'area' in prop_name \
|
||||||
and 'side' in prop_name:
|
and 'side' in prop_name:
|
||||||
@@ -62,6 +62,21 @@ class QtoCalculator():
|
|||||||
return (Vector(o.bound_box[1]) - Vector(o.bound_box[0])).length
|
return (Vector(o.bound_box[1]) - Vector(o.bound_box[0])).length
|
||||||
|
|
||||||
def get_perimeter(self, o):
|
def get_perimeter(self, o):
|
||||||
|
parsed_edges = []
|
||||||
|
shared_edges = []
|
||||||
|
perimeter = 0
|
||||||
|
for polygon in self.get_lowest_polygons(o):
|
||||||
|
for edge_key in polygon.edge_keys:
|
||||||
|
if edge_key in parsed_edges:
|
||||||
|
shared_edges.append(edge_key)
|
||||||
|
else:
|
||||||
|
parsed_edges.append(edge_key)
|
||||||
|
perimeter += self.get_edge_key_distance(o, edge_key)
|
||||||
|
for edge_key in shared_edges:
|
||||||
|
perimeter -= self.get_edge_key_distance(o, edge_key)
|
||||||
|
return perimeter
|
||||||
|
|
||||||
|
def get_lowest_polygons(self, o):
|
||||||
lowest_polygons = []
|
lowest_polygons = []
|
||||||
lowest_z = None
|
lowest_z = None
|
||||||
for polygon in o.data.polygons:
|
for polygon in o.data.polygons:
|
||||||
@@ -75,19 +90,7 @@ class QtoCalculator():
|
|||||||
elif z < lowest_z:
|
elif z < lowest_z:
|
||||||
lowest_polygons = [polygon]
|
lowest_polygons = [polygon]
|
||||||
lowest_z = z
|
lowest_z = z
|
||||||
parsed_edges = []
|
return lowest_polygons
|
||||||
shared_edges = []
|
|
||||||
perimeter = 0
|
|
||||||
for polygon in lowest_polygons:
|
|
||||||
for edge_key in polygon.edge_keys:
|
|
||||||
if edge_key in parsed_edges:
|
|
||||||
shared_edges.append(edge_key)
|
|
||||||
else:
|
|
||||||
parsed_edges.append(edge_key)
|
|
||||||
perimeter += self.get_edge_key_distance(o, edge_key)
|
|
||||||
for edge_key in shared_edges:
|
|
||||||
perimeter -= self.get_edge_key_distance(o, edge_key)
|
|
||||||
return perimeter
|
|
||||||
|
|
||||||
def get_edge_key_distance(self, obj, edge_key):
|
def get_edge_key_distance(self, obj, edge_key):
|
||||||
return (obj.data.vertices[edge_key[1]].co - obj.data.vertices[edge_key[0]].co).length
|
return (obj.data.vertices[edge_key[1]].co - obj.data.vertices[edge_key[0]].co).length
|
||||||
@@ -97,10 +100,8 @@ class QtoCalculator():
|
|||||||
|
|
||||||
def get_footprint_area(self, o):
|
def get_footprint_area(self, o):
|
||||||
area = 0
|
area = 0
|
||||||
for polygon in o.data.polygons:
|
for polygon in self.get_lowest_polygons(o):
|
||||||
if round(polygon.center[2], 3) == 0.0 \
|
area += polygon.area
|
||||||
and round(o.data.vertices[polygon.vertices[0]].co[2], 3) == 0.0:
|
|
||||||
area += polygon.area
|
|
||||||
return area
|
return area
|
||||||
|
|
||||||
def get_side_area(self, o):
|
def get_side_area(self, o):
|
||||||
|
|||||||
Reference in New Issue
Block a user