mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Finish mapping Qto_BeamBaseQuantities
This commit is contained in:
committed by
Dion Moult
parent
a7febaa9b0
commit
bfb2f06e44
@@ -470,13 +470,13 @@ mapper = {
|
||||
'NetWeight' : None,
|
||||
},
|
||||
'Qto_BeamBaseQuantities' : {
|
||||
'Length' : None,
|
||||
'CrossSectionArea' : None,
|
||||
'OuterSurfaceArea' : None,
|
||||
'GrossSurfaceArea' : None,
|
||||
'NetSurfaceArea' : None,
|
||||
'GrossVolume' : None,
|
||||
'NetVolume' : None,
|
||||
'Length' : "get_length",
|
||||
'CrossSectionArea' : { "function_name" : "get_end_area", "args" : ", exclude_side_areas = True" },
|
||||
'GrossSurfaceArea' : { "function_name" : "get_gross_lateral_area", "args" : ", exclude_end_areas = False, angle_z1 = 0, angle_z2 = 360" },
|
||||
'OuterSurfaceArea' : { "function_name" : "get_lateral_area", "args" : ", exclude_end_areas = True, angle_z1 = 0, angle_z2 = 360" },
|
||||
'NetSurfaceArea' : { "function_name" : "get_lateral_area", "args" : ", exclude_end_areas = False, angle_z1 = 0, angle_z2 = 360" },
|
||||
'GrossVolume' : "get_gross_volume",
|
||||
'NetVolume' : "get_net_volume",
|
||||
'GrossWeight' : None,
|
||||
'NetWeight' : None,
|
||||
},
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
So, here are some note needed to know about how quantities are calculated.
|
||||
|
||||
NET VOLUME AND GROSS VOLUME
|
||||
The difference between gross volume and net volume is that the gross volume is calculated
|
||||
without the related IFC opening.
|
||||
So, if an object is created lets say with a hole but without defining the opening, the hole is counted into net volume (so get volume and net volume are the same).
|
||||
This is in order to follow the native IFC approach.
|
||||
|
||||
WALLS AND BEAM LENGTH, HEIGHT, WIDTH AND LATERAL AREA
|
||||
These dimensions are calculated with the convention that the object can have main axis along x or z.
|
||||
The same with lateral area.
|
||||
|
||||
SLAB THICKNESS
|
||||
The slab thickness is defined as Width, following the IFC definition
|
||||
Also, note that these dimensions are calculated only if the slab is prismatic.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -96,10 +96,13 @@ class QtoCalculator:
|
||||
return max(x, y, z)
|
||||
|
||||
def get_length(self, o, vg_index=None):
|
||||
if vg_index is None:
|
||||
if vg_index is None and not self.has_local_axes_rotated(o):
|
||||
x = (Vector(o.bound_box[4]) - Vector(o.bound_box[0])).length
|
||||
y = (Vector(o.bound_box[3]) - Vector(o.bound_box[0])).length
|
||||
return max(x, y)
|
||||
if vg_index is None and self.has_local_axes_rotated(o):
|
||||
return ((Vector(o.bound_box[1]) - Vector(o.bound_box[0])).length)
|
||||
|
||||
length = 0
|
||||
edges = [
|
||||
e
|
||||
@@ -425,9 +428,16 @@ class QtoCalculator:
|
||||
:param int angle_z2: Angle measured from the positive z-axis to the normal-vector of the area. Openings with a normal_vector greater than this value will be ignored, defaults to 135
|
||||
:return float: Lateral Area
|
||||
"""
|
||||
x_axis = [1, 0, 0]
|
||||
y_axis = [0, 1, 0]
|
||||
z_axis = [0, 0, 1]
|
||||
|
||||
if not self.has_local_axes_rotated(obj):
|
||||
x_axis = [1, 0, 0]
|
||||
y_axis = [0, 1, 0]
|
||||
z_axis = [0, 0, 1]
|
||||
if self.has_local_axes_rotated(obj):
|
||||
x_axis = [0, 0, 1]
|
||||
y_axis = [1, 0, 0]
|
||||
z_axis = [0, 1, 0]
|
||||
|
||||
area = 0
|
||||
total_opening_area = (
|
||||
0 if subtract_openings else self.get_opening_area(obj, angle_z1=angle_z1, angle_z2=angle_z2)
|
||||
@@ -447,10 +457,45 @@ class QtoCalculator:
|
||||
if angle_to_y_axis < 45 or angle_to_y_axis > 135:
|
||||
continue
|
||||
area += polygon.area
|
||||
|
||||
return area + total_opening_area
|
||||
|
||||
def get_gross_lateral_area(
|
||||
self,
|
||||
obj,
|
||||
subtract_openings: bool = True,
|
||||
exclude_end_areas: bool = False,
|
||||
exclude_side_areas: bool = False,
|
||||
angle_z1: int = 45,
|
||||
angle_z2: int = 135,
|
||||
):
|
||||
"""_summary_
|
||||
|
||||
:param blender-object obj: blender object, bpy.types.Object
|
||||
:param bool subtract_openings: Toggle whether opening-areas should be subtracted, defaults to True
|
||||
:param bool exclude_end_areas: , defaults to False
|
||||
:param bool exclude_side_areas: , defaults to False
|
||||
:param int angle_z1: Angle measured from the positive z-axis to the normal-vector of the area. Openings with a normal_vector lower than this value will be ignored, defaults to 45
|
||||
:param int angle_z2: Angle measured from the positive z-axis to the normal-vector of the area. Openings with a normal_vector greater than this value will be ignored, defaults to 135
|
||||
:return float: Lateral gross Area
|
||||
"""
|
||||
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
|
||||
gross_mesh = self.get_gross_element_mesh(element)
|
||||
|
||||
gross_obj = bpy.data.objects.new("MyObject", gross_mesh)
|
||||
|
||||
gross_lateral_area = self.get_lateral_area(gross_obj, subtract_openings, exclude_end_areas, exclude_side_areas, angle_z1, angle_z2 )
|
||||
|
||||
self.delete_obj(gross_obj)
|
||||
self.delete_mesh(gross_mesh)
|
||||
|
||||
return gross_lateral_area
|
||||
|
||||
|
||||
def get_half_lateral_area(
|
||||
self,
|
||||
self,
|
||||
obj,
|
||||
subtract_openings: bool = True,
|
||||
exclude_end_areas: bool = False,
|
||||
@@ -469,6 +514,29 @@ class QtoCalculator:
|
||||
"""
|
||||
return self.get_lateral_area(obj, subtract_openings, exclude_end_areas, exclude_side_areas, angle_z1, angle_z2)/2
|
||||
|
||||
def get_end_area(
|
||||
self,
|
||||
obj,
|
||||
subtract_openings: bool = True,
|
||||
exclude_end_areas: bool = False,
|
||||
exclude_side_areas: bool = False,
|
||||
angle_z1: int = 45,
|
||||
angle_z2: int = 135,
|
||||
):
|
||||
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
gross_mesh = self.get_gross_element_mesh(element)
|
||||
|
||||
gross_obj = bpy.data.objects.new("MyObject", gross_mesh)
|
||||
gross_obj.matrix_world = obj.matrix_world
|
||||
|
||||
end_area = self.get_lateral_area(gross_obj, subtract_openings, exclude_end_areas, exclude_side_areas, angle_z1, angle_z2)/2
|
||||
|
||||
self.delete_obj(gross_obj)
|
||||
self.delete_mesh(gross_mesh)
|
||||
|
||||
return end_area
|
||||
|
||||
def get_gross_top_area(self, obj, angle: int = 45):
|
||||
"""_summary_: Returns the gross top area of the object.
|
||||
|
||||
@@ -888,6 +956,13 @@ class QtoCalculator:
|
||||
bm.from_mesh(mesh)
|
||||
return bm
|
||||
|
||||
def has_local_axes_rotated(self, o):
|
||||
matrix = o.matrix_world
|
||||
if matrix[0][0] == 1:
|
||||
return False
|
||||
if matrix[0][2] == 1:
|
||||
return True
|
||||
|
||||
def delete_mesh(self, mesh):
|
||||
mesh.user_clear()
|
||||
bpy.data.meshes.remove(mesh)
|
||||
|
||||
Reference in New Issue
Block a user