mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-28 15:53:00 +00:00
typing
This commit is contained in:
@@ -29,6 +29,7 @@ from mathutils.bvhtree import BVHTree
|
|||||||
from shapely.geometry import Polygon
|
from shapely.geometry import Polygon
|
||||||
from shapely.ops import unary_union
|
from shapely.ops import unary_union
|
||||||
from typing import Literal, Union, Optional
|
from typing import Literal, Union, Optional
|
||||||
|
from typing_extensions import assert_never
|
||||||
|
|
||||||
|
|
||||||
AxisType = Literal["x", "y", "z"]
|
AxisType = Literal["x", "y", "z"]
|
||||||
@@ -51,6 +52,7 @@ def get_z(o: bpy.types.Object) -> float:
|
|||||||
|
|
||||||
|
|
||||||
def get_units(o: bpy.types.Object, vg_index: int) -> int:
|
def get_units(o: bpy.types.Object, vg_index: int) -> int:
|
||||||
|
assert isinstance(o.data, bpy.types.Mesh)
|
||||||
return len([v for v in o.data.vertices if vg_index in [g.group for g in v.groups]])
|
return len([v for v in o.data.vertices if vg_index in [g.group for g in v.groups]])
|
||||||
|
|
||||||
|
|
||||||
@@ -72,11 +74,12 @@ def get_length(o: bpy.types.Object, vg_index: Optional[int] = None) -> float:
|
|||||||
x = get_x(o)
|
x = get_x(o)
|
||||||
y = get_y(o)
|
y = get_y(o)
|
||||||
z = get_z(o)
|
z = get_z(o)
|
||||||
if get_object_main_axis(o) == "x":
|
main_axis_guess = get_object_main_axis(o)
|
||||||
|
if main_axis_guess == "x":
|
||||||
return max(x, y)
|
return max(x, y)
|
||||||
if get_object_main_axis(o) == "z":
|
elif main_axis_guess == "z":
|
||||||
return max(z, x)
|
return max(z, x)
|
||||||
if get_object_main_axis(o) == "y":
|
elif main_axis_guess == "y":
|
||||||
return max(y, z)
|
return max(y, z)
|
||||||
|
|
||||||
length = 0
|
length = 0
|
||||||
@@ -114,7 +117,9 @@ def get_gross_stair_area(obj: bpy.types.Object) -> float:
|
|||||||
|
|
||||||
|
|
||||||
def get_parametric_axis(obj: bpy.types.Object) -> Literal["AXIS2", "AXIS3", None]:
|
def get_parametric_axis(obj: bpy.types.Object) -> Literal["AXIS2", "AXIS3", None]:
|
||||||
relating_type = ifcopenshell.util.element.get_type(tool.Ifc.get_entity(obj))
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
|
relating_type = ifcopenshell.util.element.get_type(element)
|
||||||
if relating_type:
|
if relating_type:
|
||||||
parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric")
|
parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric")
|
||||||
if parametric:
|
if parametric:
|
||||||
@@ -137,6 +142,8 @@ def get_covering_gross_area(obj: bpy.types.Object) -> float:
|
|||||||
return get_gross_side_area(obj)
|
return get_gross_side_area(obj)
|
||||||
elif parametrix_axis == "AXIS3":
|
elif parametrix_axis == "AXIS3":
|
||||||
return get_gross_footprint_area(obj)
|
return get_gross_footprint_area(obj)
|
||||||
|
else:
|
||||||
|
assert_never(parametrix_axis)
|
||||||
|
|
||||||
|
|
||||||
def get_covering_net_area(obj: bpy.types.Object) -> float:
|
def get_covering_net_area(obj: bpy.types.Object) -> float:
|
||||||
@@ -147,6 +154,8 @@ def get_covering_net_area(obj: bpy.types.Object) -> float:
|
|||||||
return get_net_side_area(obj)
|
return get_net_side_area(obj)
|
||||||
elif parametrix_axis == "AXIS3":
|
elif parametrix_axis == "AXIS3":
|
||||||
return get_net_footprint_area(obj)
|
return get_net_footprint_area(obj)
|
||||||
|
else:
|
||||||
|
assert_never(parametrix_axis)
|
||||||
|
|
||||||
|
|
||||||
def get_covering_width(obj: bpy.types.Object) -> float:
|
def get_covering_width(obj: bpy.types.Object) -> float:
|
||||||
@@ -157,6 +166,8 @@ def get_covering_width(obj: bpy.types.Object) -> float:
|
|||||||
return get_width(obj)
|
return get_width(obj)
|
||||||
elif parametrix_axis == "AXIS3":
|
elif parametrix_axis == "AXIS3":
|
||||||
return get_height(obj)
|
return get_height(obj)
|
||||||
|
else:
|
||||||
|
assert_never(parametrix_axis)
|
||||||
|
|
||||||
|
|
||||||
def get_width(o: bpy.types.Object) -> float:
|
def get_width(o: bpy.types.Object) -> float:
|
||||||
@@ -225,6 +236,7 @@ def get_finish_floor_height(obj: bpy.types.Object) -> float:
|
|||||||
space_min_z_value = get_min_global_z(obj)
|
space_min_z_value = get_min_global_z(obj)
|
||||||
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
decompositions = ifcopenshell.util.element.get_decomposition(element)
|
decompositions = ifcopenshell.util.element.get_decomposition(element)
|
||||||
flooring_max_z_value = space_min_z_value
|
flooring_max_z_value = space_min_z_value
|
||||||
for decomposition in decompositions:
|
for decomposition in decompositions:
|
||||||
@@ -233,6 +245,7 @@ def get_finish_floor_height(obj: bpy.types.Object) -> float:
|
|||||||
and ifcopenshell.util.element.get_predefined_type(decomposition) == "FLOORING"
|
and ifcopenshell.util.element.get_predefined_type(decomposition) == "FLOORING"
|
||||||
):
|
):
|
||||||
flooring_obj = tool.Ifc.get_object(decomposition)
|
flooring_obj = tool.Ifc.get_object(decomposition)
|
||||||
|
assert isinstance(flooring_obj, bpy.types.Object)
|
||||||
flooring_z_value = get_max_global_z(flooring_obj)
|
flooring_z_value = get_max_global_z(flooring_obj)
|
||||||
if flooring_z_value > space_min_z_value:
|
if flooring_z_value > space_min_z_value:
|
||||||
flooring_max_z_value = flooring_z_value
|
flooring_max_z_value = flooring_z_value
|
||||||
@@ -245,6 +258,7 @@ def get_ceiling_height(obj: bpy.types.Object) -> float:
|
|||||||
space_max_z_value = get_max_global_z(obj)
|
space_max_z_value = get_max_global_z(obj)
|
||||||
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
decompositions = ifcopenshell.util.element.get_decomposition(element)
|
decompositions = ifcopenshell.util.element.get_decomposition(element)
|
||||||
ceiling_min_z_value = space_max_z_value
|
ceiling_min_z_value = space_max_z_value
|
||||||
for decomposition in decompositions:
|
for decomposition in decompositions:
|
||||||
@@ -253,6 +267,7 @@ def get_ceiling_height(obj: bpy.types.Object) -> float:
|
|||||||
and ifcopenshell.util.element.get_predefined_type(decomposition) == "CEILING"
|
and ifcopenshell.util.element.get_predefined_type(decomposition) == "CEILING"
|
||||||
):
|
):
|
||||||
ceiling_obj = tool.Ifc.get_object(decomposition)
|
ceiling_obj = tool.Ifc.get_object(decomposition)
|
||||||
|
assert isinstance(ceiling_obj, bpy.types.Object)
|
||||||
ceiling_z_value = get_min_global_z(ceiling_obj)
|
ceiling_z_value = get_min_global_z(ceiling_obj)
|
||||||
if ceiling_z_value < space_max_z_value:
|
if ceiling_z_value < space_max_z_value:
|
||||||
ceiling_min_z_value = ceiling_z_value
|
ceiling_min_z_value = ceiling_z_value
|
||||||
@@ -300,6 +315,7 @@ def get_rectangular_perimeter(obj: bpy.types.Object) -> float:
|
|||||||
def get_lowest_polygons(o: bpy.types.Object) -> list[bpy.types.MeshPolygon]:
|
def get_lowest_polygons(o: bpy.types.Object) -> list[bpy.types.MeshPolygon]:
|
||||||
lowest_polygons = []
|
lowest_polygons = []
|
||||||
lowest_z = None
|
lowest_z = None
|
||||||
|
assert isinstance(o.data, bpy.types.Mesh)
|
||||||
for polygon in o.data.polygons:
|
for polygon in o.data.polygons:
|
||||||
z = round(polygon.center[2], 3)
|
z = round(polygon.center[2], 3)
|
||||||
if lowest_z is None:
|
if lowest_z is None:
|
||||||
@@ -317,6 +333,7 @@ def get_lowest_polygons(o: bpy.types.Object) -> list[bpy.types.MeshPolygon]:
|
|||||||
def get_highest_polygons(o: bpy.types.Object) -> list[bpy.types.MeshPolygon]:
|
def get_highest_polygons(o: bpy.types.Object) -> list[bpy.types.MeshPolygon]:
|
||||||
highest_polygons = []
|
highest_polygons = []
|
||||||
highest_z = None
|
highest_z = None
|
||||||
|
assert isinstance(o.data, bpy.types.Mesh)
|
||||||
for polygon in o.data.polygons:
|
for polygon in o.data.polygons:
|
||||||
z = round(polygon.center[2], 3)
|
z = round(polygon.center[2], 3)
|
||||||
if highest_z is None:
|
if highest_z is None:
|
||||||
@@ -332,10 +349,12 @@ def get_highest_polygons(o: bpy.types.Object) -> list[bpy.types.MeshPolygon]:
|
|||||||
|
|
||||||
|
|
||||||
def get_edge_key_distance(obj: bpy.types.Object, edge_key: tuple[int, int]) -> float:
|
def get_edge_key_distance(obj: bpy.types.Object, edge_key: tuple[int, int]) -> float:
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
def get_edge_distance(obj: bpy.types.Object, edge: bpy.types.MeshEdge) -> float:
|
def get_edge_distance(obj: bpy.types.Object, edge: bpy.types.MeshEdge) -> float:
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
return (obj.data.vertices[edge.vertices[1]].co - obj.data.vertices[edge.vertices[0]].co).length
|
return (obj.data.vertices[edge.vertices[1]].co - obj.data.vertices[edge.vertices[0]].co).length
|
||||||
|
|
||||||
|
|
||||||
@@ -350,6 +369,7 @@ def get_net_floor_area(obj: bpy.types.Object) -> float:
|
|||||||
decomposition_type = decomposition.get_info()["type"]
|
decomposition_type = decomposition.get_info()["type"]
|
||||||
if decomposition_type == "IfcColumn" or decomposition_type == "IfcColumn":
|
if decomposition_type == "IfcColumn" or decomposition_type == "IfcColumn":
|
||||||
decomposition_obj = tool.Ifc.get_object(decomposition)
|
decomposition_obj = tool.Ifc.get_object(decomposition)
|
||||||
|
assert isinstance(decomposition_obj, bpy.types.Object)
|
||||||
net_footprint_obj_area = get_net_footprint_area(decomposition_obj)
|
net_footprint_obj_area = get_net_footprint_area(decomposition_obj)
|
||||||
total_net_floor_area -= net_footprint_obj_area
|
total_net_floor_area -= net_footprint_obj_area
|
||||||
|
|
||||||
@@ -368,6 +388,7 @@ def get_gross_ceiling_area(obj: bpy.types.Object) -> float:
|
|||||||
decomposition_predefined_type = ifcopenshell.util.element.get_predefined_type(decomposition)
|
decomposition_predefined_type = ifcopenshell.util.element.get_predefined_type(decomposition)
|
||||||
if decomposition_class == "IfcCovering" and decomposition_predefined_type == "CEILING":
|
if decomposition_class == "IfcCovering" and decomposition_predefined_type == "CEILING":
|
||||||
decomposition_obj = tool.Ifc.get_object(decomposition)
|
decomposition_obj = tool.Ifc.get_object(decomposition)
|
||||||
|
assert isinstance(decomposition_obj, bpy.types.Object)
|
||||||
total_gross_ceiling_area += get_gross_footprint_area(decomposition_obj)
|
total_gross_ceiling_area += get_gross_footprint_area(decomposition_obj)
|
||||||
|
|
||||||
return total_gross_ceiling_area
|
return total_gross_ceiling_area
|
||||||
@@ -385,10 +406,12 @@ def get_net_ceiling_area(obj: bpy.types.Object) -> float:
|
|||||||
decomposition_predefined_type = ifcopenshell.util.element.get_predefined_type(decomposition)
|
decomposition_predefined_type = ifcopenshell.util.element.get_predefined_type(decomposition)
|
||||||
if decomposition_class == "IfcCovering" and decomposition_predefined_type == "CEILING":
|
if decomposition_class == "IfcCovering" and decomposition_predefined_type == "CEILING":
|
||||||
decomposition_obj = tool.Ifc.get_object(decomposition)
|
decomposition_obj = tool.Ifc.get_object(decomposition)
|
||||||
|
assert isinstance(decomposition_obj, bpy.types.Object)
|
||||||
total_net_ceiling_area += get_net_footprint_area(decomposition_obj)
|
total_net_ceiling_area += get_net_footprint_area(decomposition_obj)
|
||||||
|
|
||||||
if decomposition_class == "IfcWall" or decomposition_class == "IfcColumn":
|
if decomposition_class == "IfcWall" or decomposition_class == "IfcColumn":
|
||||||
decomposition_obj = tool.Ifc.get_object(decomposition)
|
decomposition_obj = tool.Ifc.get_object(decomposition)
|
||||||
|
assert isinstance(decomposition_obj, bpy.types.Object)
|
||||||
total_net_ceiling_area -= get_net_roofprint_area(decomposition_obj)
|
total_net_ceiling_area -= get_net_roofprint_area(decomposition_obj)
|
||||||
|
|
||||||
return total_net_ceiling_area
|
return total_net_ceiling_area
|
||||||
@@ -405,6 +428,7 @@ def get_space_net_volume(obj: bpy.types.Object) -> float:
|
|||||||
decomposition_type = decomposition.get_info()["type"]
|
decomposition_type = decomposition.get_info()["type"]
|
||||||
if decomposition_type == "IfcWall" or decomposition_type == "IfcColumn":
|
if decomposition_type == "IfcWall" or decomposition_type == "IfcColumn":
|
||||||
decomposition_obj = tool.Ifc.get_object(decomposition)
|
decomposition_obj = tool.Ifc.get_object(decomposition)
|
||||||
|
assert isinstance(decomposition_obj, bpy.types.Object)
|
||||||
total_space_net_volume -= get_net_volume(decomposition_obj)
|
total_space_net_volume -= get_net_volume(decomposition_obj)
|
||||||
|
|
||||||
return total_space_net_volume
|
return total_space_net_volume
|
||||||
@@ -493,6 +517,7 @@ def get_gross_surface_area(o: bpy.types.Object, vg_index: Optional[int] = None)
|
|||||||
return area
|
return area
|
||||||
|
|
||||||
area = 0
|
area = 0
|
||||||
|
assert isinstance(o.data, bpy.types.Mesh)
|
||||||
vertices_in_vg = [v.index for v in o.data.vertices if vg_index in [g.group for g in v.groups]]
|
vertices_in_vg = [v.index for v in o.data.vertices if vg_index in [g.group for g in v.groups]]
|
||||||
for polygon in o.data.polygons:
|
for polygon in o.data.polygons:
|
||||||
if is_polygon_in_vg(polygon, vertices_in_vg):
|
if is_polygon_in_vg(polygon, vertices_in_vg):
|
||||||
@@ -501,6 +526,7 @@ def get_gross_surface_area(o: bpy.types.Object, vg_index: Optional[int] = None)
|
|||||||
|
|
||||||
|
|
||||||
def get_net_surface_area(obj: bpy.types.Object) -> float:
|
def get_net_surface_area(obj: bpy.types.Object) -> float:
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
return get_mesh_area(obj.data)
|
return get_mesh_area(obj.data)
|
||||||
|
|
||||||
|
|
||||||
@@ -511,7 +537,7 @@ def get_mesh_area(mesh: bpy.types.Mesh) -> float:
|
|||||||
return area
|
return area
|
||||||
|
|
||||||
|
|
||||||
def is_polygon_in_vg(polygon: bpy.types.MeshPolygon, vertices_in_vg: list[bpy.types.MeshVertex]) -> bool:
|
def is_polygon_in_vg(polygon: bpy.types.MeshPolygon, vertices_in_vg: list[int]) -> bool:
|
||||||
for v in polygon.vertices:
|
for v in polygon.vertices:
|
||||||
if v not in vertices_in_vg:
|
if v not in vertices_in_vg:
|
||||||
return False
|
return False
|
||||||
@@ -553,6 +579,7 @@ def has_openings(obj: bpy.types.Object) -> list[ifcopenshell.entity_instance]:
|
|||||||
|
|
||||||
def get_obj_decompositions(obj: bpy.types.Object) -> set[ifcopenshell.entity_instance]:
|
def get_obj_decompositions(obj: bpy.types.Object) -> set[ifcopenshell.entity_instance]:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
decompositions = ifcopenshell.util.element.get_decomposition(element)
|
decompositions = ifcopenshell.util.element.get_decomposition(element)
|
||||||
return decompositions
|
return decompositions
|
||||||
|
|
||||||
@@ -591,6 +618,7 @@ def get_opening_type(opening: bpy.types.Object, obj: bpy.types.Object) -> Litera
|
|||||||
:param blender-object obj: blender object
|
:param blender-object obj: blender object
|
||||||
:return string: "OPENING" or "RECESS"
|
:return string: "OPENING" or "RECESS"
|
||||||
"""
|
"""
|
||||||
|
assert isinstance(opening.data, bpy.types.Mesh)
|
||||||
polygons = opening.data.polygons
|
polygons = opening.data.polygons
|
||||||
ray_intersections = 0
|
ray_intersections = 0
|
||||||
|
|
||||||
@@ -687,21 +715,25 @@ def get_lateral_area(
|
|||||||
y_axis = [0, 1, 0]
|
y_axis = [0, 1, 0]
|
||||||
z_axis = [0, 0, 1]
|
z_axis = [0, 0, 1]
|
||||||
|
|
||||||
if get_object_main_axis(obj) == "x" or main_axis == "x":
|
main_axis_guess = get_object_main_axis(obj)
|
||||||
main_axis = x_axis
|
if main_axis_guess == "x" or main_axis == "x":
|
||||||
|
main_axis_v = x_axis
|
||||||
side_axis = y_axis
|
side_axis = y_axis
|
||||||
top_axis = z_axis
|
top_axis = z_axis
|
||||||
elif get_object_main_axis(obj) == "z":
|
elif main_axis_guess == "z":
|
||||||
main_axis = z_axis
|
main_axis_v = z_axis
|
||||||
side_axis = x_axis
|
side_axis = x_axis
|
||||||
top_axis = y_axis
|
top_axis = y_axis
|
||||||
elif get_object_main_axis(obj) == "y":
|
elif main_axis_guess == "y":
|
||||||
main_axis = y_axis
|
main_axis_v = y_axis
|
||||||
side_axis = z_axis
|
side_axis = z_axis
|
||||||
top_axis = x_axis
|
top_axis = x_axis
|
||||||
|
else:
|
||||||
|
assert_never(main_axis_guess)
|
||||||
|
|
||||||
area = 0
|
area = 0
|
||||||
total_opening_area = 0 if subtract_openings else get_opening_area(obj, angle_z1=angle_z1, angle_z2=angle_z2)
|
total_opening_area = 0 if subtract_openings else get_opening_area(obj, angle_z1=angle_z1, angle_z2=angle_z2)
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
polygons = obj.data.polygons
|
polygons = obj.data.polygons
|
||||||
|
|
||||||
for polygon in polygons:
|
for polygon in polygons:
|
||||||
@@ -709,7 +741,7 @@ def get_lateral_area(
|
|||||||
if angle_to_top_axis < angle_z1 or angle_to_top_axis > angle_z2:
|
if angle_to_top_axis < angle_z1 or angle_to_top_axis > angle_z2:
|
||||||
continue
|
continue
|
||||||
if exclude_end_areas:
|
if exclude_end_areas:
|
||||||
angle_to_main_axis = math.degrees(polygon.normal.rotation_difference(Vector(main_axis)).angle)
|
angle_to_main_axis = math.degrees(polygon.normal.rotation_difference(Vector(main_axis_v)).angle)
|
||||||
if angle_to_main_axis < 45 or angle_to_main_axis > 135:
|
if angle_to_main_axis < 45 or angle_to_main_axis > 135:
|
||||||
continue
|
continue
|
||||||
if exclude_side_areas:
|
if exclude_side_areas:
|
||||||
@@ -779,6 +811,7 @@ def get_gross_top_area(obj: bpy.types.Object, angle: float = 45) -> float:
|
|||||||
|
|
||||||
entity = ifc.by_guid(opening_id)
|
entity = ifc.by_guid(opening_id)
|
||||||
open_obj = tool.Ifc.get_object(entity)
|
open_obj = tool.Ifc.get_object(entity)
|
||||||
|
assert isinstance(open_obj, bpy.types.Object)
|
||||||
opening_area += get_net_top_area(open_obj, angle=angle)
|
opening_area += get_net_top_area(open_obj, angle=angle)
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
@@ -911,6 +944,7 @@ def get_AABB_object(obj: bpy.types.Object) -> bpy.types.Object:
|
|||||||
ifc_id = tool.Blender.get_ifc_definition_id(obj)
|
ifc_id = tool.Blender.get_ifc_definition_id(obj)
|
||||||
aabb_mesh = bpy.data.meshes.new(f"OBB_{ifc_id}")
|
aabb_mesh = bpy.data.meshes.new(f"OBB_{ifc_id}")
|
||||||
|
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
x = [v.co.x for v in obj.data.vertices]
|
x = [v.co.x for v in obj.data.vertices]
|
||||||
y = [v.co.y for v in obj.data.vertices]
|
y = [v.co.y for v in obj.data.vertices]
|
||||||
z = [v.co.z for v in obj.data.vertices]
|
z = [v.co.z for v in obj.data.vertices]
|
||||||
@@ -976,6 +1010,7 @@ def get_bisected_obj(
|
|||||||
ifc_id = tool.Blender.get_ifc_definition_id(obj)
|
ifc_id = tool.Blender.get_ifc_definition_id(obj)
|
||||||
|
|
||||||
bis_obj = obj.copy()
|
bis_obj = obj.copy()
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
bis_obj.data = obj.data.copy()
|
bis_obj.data = obj.data.copy()
|
||||||
bis_obj.name = f"Bisected_{ifc_id}"
|
bis_obj.name = f"Bisected_{ifc_id}"
|
||||||
|
|
||||||
@@ -1033,6 +1068,7 @@ def get_touching_objects(obj: bpy.types.Object, class_filter: list[str]) -> list
|
|||||||
obj.rotation_euler[1] += math.radians(0.001)
|
obj.rotation_euler[1] += math.radians(0.001)
|
||||||
bpy.context.evaluated_depsgraph_get().update()
|
bpy.context.evaluated_depsgraph_get().update()
|
||||||
|
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
obj_mesh = bmesh.new()
|
obj_mesh = bmesh.new()
|
||||||
obj_mesh.from_mesh(obj.data)
|
obj_mesh.from_mesh(obj.data)
|
||||||
obj_mesh.transform(obj.matrix_world)
|
obj_mesh.transform(obj.matrix_world)
|
||||||
@@ -1045,11 +1081,14 @@ def get_touching_objects(obj: bpy.types.Object, class_filter: list[str]) -> list
|
|||||||
for f in class_filter:
|
for f in class_filter:
|
||||||
filtered_objects += ifc.by_type(f)
|
filtered_objects += ifc.by_type(f)
|
||||||
|
|
||||||
|
blender_o = None
|
||||||
for o in filtered_objects:
|
for o in filtered_objects:
|
||||||
blender_o = tool.Ifc.get_object(o)
|
blender_o = tool.Ifc.get_object(o)
|
||||||
if blender_o == obj:
|
if blender_o == obj:
|
||||||
continue
|
continue
|
||||||
o_mesh = bmesh.new()
|
o_mesh = bmesh.new()
|
||||||
|
assert isinstance(blender_o, bpy.types.Object)
|
||||||
|
assert isinstance(blender_o.data, bpy.types.Mesh)
|
||||||
try:
|
try:
|
||||||
o_mesh.from_mesh(blender_o.data)
|
o_mesh.from_mesh(blender_o.data)
|
||||||
except:
|
except:
|
||||||
@@ -1062,6 +1101,7 @@ def get_touching_objects(obj: bpy.types.Object, class_filter: list[str]) -> list
|
|||||||
touching_objects.append(blender_o)
|
touching_objects.append(blender_o)
|
||||||
|
|
||||||
# return the objects to their original states
|
# return the objects to their original states
|
||||||
|
assert isinstance(blender_o, bpy.types.Object)
|
||||||
blender_o.rotation_euler[0] -= math.radians(0.001)
|
blender_o.rotation_euler[0] -= math.radians(0.001)
|
||||||
blender_o.rotation_euler[1] -= math.radians(0.001)
|
blender_o.rotation_euler[1] -= math.radians(0.001)
|
||||||
bpy.context.evaluated_depsgraph_get().update()
|
bpy.context.evaluated_depsgraph_get().update()
|
||||||
@@ -1079,6 +1119,8 @@ def get_contact_area(object1: bpy.types.Object, object2: bpy.types.Object) -> fl
|
|||||||
# list of tuples, each tuple containing the index of the polygon in object1 and object2 that are touching
|
# list of tuples, each tuple containing the index of the polygon in object1 and object2 that are touching
|
||||||
total_area = 0
|
total_area = 0
|
||||||
|
|
||||||
|
assert isinstance(object1.data, bpy.types.Mesh)
|
||||||
|
assert isinstance(object2.data, bpy.types.Mesh)
|
||||||
for poly1 in object1.data.polygons:
|
for poly1 in object1.data.polygons:
|
||||||
for poly2 in object2.data.polygons:
|
for poly2 in object2.data.polygons:
|
||||||
total_area += get_intersection_between_polygons(object1, poly1, object2, poly2)
|
total_area += get_intersection_between_polygons(object1, poly1, object2, poly2)
|
||||||
@@ -1144,6 +1186,7 @@ def create_shapely_polygon(obj: bpy.types.Object, polygon: bpy.types.MeshPolygon
|
|||||||
"""
|
"""
|
||||||
polygon_tuples = []
|
polygon_tuples = []
|
||||||
odata = obj.data
|
odata = obj.data
|
||||||
|
assert isinstance(odata, bpy.types.Mesh)
|
||||||
for loop_index in polygon.loop_indices:
|
for loop_index in polygon.loop_indices:
|
||||||
loop = odata.loops[loop_index]
|
loop = odata.loops[loop_index]
|
||||||
coords = obj.matrix_world @ odata.vertices[loop.vertex_index].co
|
coords = obj.matrix_world @ odata.vertices[loop.vertex_index].co
|
||||||
|
|||||||
Reference in New Issue
Block a user