mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 17:57:02 +00:00
typing
This commit is contained in:
@@ -425,7 +425,7 @@ class SelectClash(bpy.types.Operator):
|
|||||||
if not clash:
|
if not clash:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
products = []
|
products: list[ifcopenshell.entity_instance] = []
|
||||||
|
|
||||||
for global_id in (clash["a_global_id"], clash["b_global_id"]):
|
for global_id in (clash["a_global_id"], clash["b_global_id"]):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import bonsai.bim.helper
|
|||||||
from bpy.types import Panel
|
from bpy.types import Panel
|
||||||
from bonsai.bim.module.clash.data import ClashData
|
from bonsai.bim.module.clash.data import ClashData
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
from typing_extensions import assert_never
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from bonsai.bim.module.clash.prop import BIMClashProperties, ClashSet, SmartClashGroup, Clash
|
from bonsai.bim.module.clash.prop import BIMClashProperties, ClashSet, SmartClashGroup, Clash
|
||||||
@@ -80,6 +81,8 @@ class BIM_PT_ifcclash(Panel):
|
|||||||
row.prop(clash_set, "clearance")
|
row.prop(clash_set, "clearance")
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(clash_set, "check_all")
|
row.prop(clash_set, "check_all")
|
||||||
|
else:
|
||||||
|
assert_never(clash_set.mode)
|
||||||
|
|
||||||
def draw_clash_set_group(group: tool.Clash.ClashSourceGroup) -> None:
|
def draw_clash_set_group(group: tool.Clash.ClashSourceGroup) -> None:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|||||||
@@ -132,14 +132,10 @@ class Clash(bonsai.core.tool.Clash):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def look_at(cls, target: Vector, location: Vector) -> None:
|
def look_at(cls, target: Vector, location: Vector) -> None:
|
||||||
camera_location = location
|
camera_location = location
|
||||||
area = tool.Blender.get_view3d_area()
|
space = tool.Blender.get_view3d_space()
|
||||||
region = next(region for region in area.regions if region.type == "WINDOW")
|
assert space and space.region_3d
|
||||||
space = next(space for space in area.spaces if space.type == "VIEW_3D")
|
|
||||||
override = {"area": area, "region": region, "space_data": space}
|
|
||||||
assert isinstance(space, bpy.types.SpaceView3D)
|
|
||||||
assert space.region_3d
|
|
||||||
space.region_3d.view_location = target
|
space.region_3d.view_location = target
|
||||||
space.region_3d.view_rotation = Vector((camera_location - target)).to_track_quat("Z", "Y")
|
space.region_3d.view_rotation = (camera_location - target).to_track_quat("Z", "Y")
|
||||||
space.region_3d.view_distance = (camera_location - target).length
|
space.region_3d.view_distance = (camera_location - target).length
|
||||||
space.shading.show_xray = True
|
space.shading.show_xray = True
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import ifcopenshell.geom
|
|||||||
import ifcopenshell.util.selector
|
import ifcopenshell.util.selector
|
||||||
from logging import Logger
|
from logging import Logger
|
||||||
from typing import Literal, TypedDict, Union
|
from typing import Literal, TypedDict, Union
|
||||||
from typing_extensions import NotRequired
|
from typing_extensions import NotRequired, assert_never
|
||||||
|
|
||||||
|
|
||||||
class ClashSource(TypedDict):
|
class ClashSource(TypedDict):
|
||||||
@@ -61,7 +61,7 @@ class ClashSet(TypedDict):
|
|||||||
a: list[ClashSource]
|
a: list[ClashSource]
|
||||||
b: NotRequired[list[ClashSource]]
|
b: NotRequired[list[ClashSource]]
|
||||||
mode: Literal["intersection", "collision", "clearance"]
|
mode: Literal["intersection", "collision", "clearance"]
|
||||||
# Added during clash.
|
# Clash results, added during clash.
|
||||||
clashes: NotRequired[dict[str, ClashResult]]
|
clashes: NotRequired[dict[str, ClashResult]]
|
||||||
# intersection, clearance modes.
|
# intersection, clearance modes.
|
||||||
check_all: NotRequired[bool]
|
check_all: NotRequired[bool]
|
||||||
@@ -74,7 +74,7 @@ class ClashSet(TypedDict):
|
|||||||
|
|
||||||
|
|
||||||
class ClashGroup(TypedDict):
|
class ClashGroup(TypedDict):
|
||||||
elements: dict
|
elements: dict[str, ifcopenshell.entity_instance]
|
||||||
objects: dict
|
objects: dict
|
||||||
|
|
||||||
|
|
||||||
@@ -110,6 +110,7 @@ class Clasher:
|
|||||||
|
|
||||||
mode = clash_set["mode"]
|
mode = clash_set["mode"]
|
||||||
if mode == "intersection":
|
if mode == "intersection":
|
||||||
|
assert "tolerance" in clash_set and "check_all" in clash_set
|
||||||
results = self.tree.clash_intersection_many(
|
results = self.tree.clash_intersection_many(
|
||||||
list(self.groups["a"]["elements"].values()),
|
list(self.groups["a"]["elements"].values()),
|
||||||
list(self.groups[b]["elements"].values()),
|
list(self.groups[b]["elements"].values()),
|
||||||
@@ -117,12 +118,14 @@ class Clasher:
|
|||||||
check_all=clash_set["check_all"],
|
check_all=clash_set["check_all"],
|
||||||
)
|
)
|
||||||
elif mode == "collision":
|
elif mode == "collision":
|
||||||
|
assert "allow_touching" in clash_set
|
||||||
results = self.tree.clash_collision_many(
|
results = self.tree.clash_collision_many(
|
||||||
list(self.groups["a"]["elements"].values()),
|
list(self.groups["a"]["elements"].values()),
|
||||||
list(self.groups[b]["elements"].values()),
|
list(self.groups[b]["elements"].values()),
|
||||||
allow_touching=clash_set["allow_touching"],
|
allow_touching=clash_set["allow_touching"],
|
||||||
)
|
)
|
||||||
elif mode == "clearance":
|
elif mode == "clearance":
|
||||||
|
assert "clearance" in clash_set and "check_all" in clash_set
|
||||||
results = self.tree.clash_clearance_many(
|
results = self.tree.clash_clearance_many(
|
||||||
list(self.groups["a"]["elements"].values()),
|
list(self.groups["a"]["elements"].values()),
|
||||||
list(self.groups[b]["elements"].values()),
|
list(self.groups[b]["elements"].values()),
|
||||||
@@ -130,7 +133,7 @@ class Clasher:
|
|||||||
check_all=clash_set["check_all"],
|
check_all=clash_set["check_all"],
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
assert False, f"Unexpected mode '{mode}'."
|
assert_never(mode)
|
||||||
|
|
||||||
processed_results: dict[str, ClashResult] = {}
|
processed_results: dict[str, ClashResult] = {}
|
||||||
for result in results:
|
for result in results:
|
||||||
@@ -144,7 +147,7 @@ class Clasher:
|
|||||||
b_ifc_class=element2.is_a(),
|
b_ifc_class=element2.is_a(),
|
||||||
a_name=element1.get_argument(2),
|
a_name=element1.get_argument(2),
|
||||||
b_name=element2.get_argument(2),
|
b_name=element2.get_argument(2),
|
||||||
type=["protrusion", "pierce", "collision", "clearance"][result.clash_type],
|
type=("protrusion", "pierce", "collision", "clearance")[result.clash_type],
|
||||||
p1=list(result.p1),
|
p1=list(result.p1),
|
||||||
p2=list(result.p2),
|
p2=list(result.p2),
|
||||||
distance=result.distance,
|
distance=result.distance,
|
||||||
@@ -173,10 +176,14 @@ class Clasher:
|
|||||||
ifc_file: ifcopenshell.file,
|
ifc_file: ifcopenshell.file,
|
||||||
source: ClashSource,
|
source: ClashSource,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
"""Process filters, add tree and group elements."""
|
||||||
|
assert self.tree
|
||||||
mode = source.get("mode")
|
mode = source.get("mode")
|
||||||
selector = source.get("selector")
|
selector = source.get("selector")
|
||||||
start = time.time()
|
start = time.time()
|
||||||
self.settings.logger.info("Creating iterator")
|
self.settings.logger.info("Creating iterator")
|
||||||
|
|
||||||
|
# Process filters.
|
||||||
if not mode or mode == "a" or not selector:
|
if not mode or mode == "a" or not selector:
|
||||||
elements = set(ifc_file.by_type("IfcElement"))
|
elements = set(ifc_file.by_type("IfcElement"))
|
||||||
elements -= set(ifc_file.by_type("IfcFeatureElement"))
|
elements -= set(ifc_file.by_type("IfcFeatureElement"))
|
||||||
@@ -186,11 +193,15 @@ class Clasher:
|
|||||||
elements -= set(ifcopenshell.util.selector.filter_elements(ifc_file, selector))
|
elements -= set(ifcopenshell.util.selector.filter_elements(ifc_file, selector))
|
||||||
elif mode == "i":
|
elif mode == "i":
|
||||||
elements = set(ifcopenshell.util.selector.filter_elements(ifc_file, selector))
|
elements = set(ifcopenshell.util.selector.filter_elements(ifc_file, selector))
|
||||||
|
else:
|
||||||
|
assert_never(mode)
|
||||||
|
|
||||||
iterator = ifcopenshell.geom.iterator(
|
iterator = ifcopenshell.geom.iterator(
|
||||||
self.geom_settings, ifc_file, multiprocessing.cpu_count(), include=elements
|
self.geom_settings, ifc_file, multiprocessing.cpu_count(), include=elements
|
||||||
)
|
)
|
||||||
self.settings.logger.info(f"Iterator creation finished {time.time() - start}")
|
self.settings.logger.info(f"Iterator creation finished {time.time() - start}")
|
||||||
|
|
||||||
|
# Add tree elements.
|
||||||
start = time.time()
|
start = time.time()
|
||||||
self.logger.info(f"Adding objects {name} ({len(elements)} elements)")
|
self.logger.info(f"Adding objects {name} ({len(elements)} elements)")
|
||||||
assert iterator.initialize()
|
assert iterator.initialize()
|
||||||
@@ -200,6 +211,8 @@ class Clasher:
|
|||||||
if not iterator.next():
|
if not iterator.next():
|
||||||
break
|
break
|
||||||
self.logger.info(f"Tree finished {time.time() - start}")
|
self.logger.info(f"Tree finished {time.time() - start}")
|
||||||
|
|
||||||
|
# Add group elements.
|
||||||
start = time.time()
|
start = time.time()
|
||||||
self.groups[name]["elements"].update({e.GlobalId: e for e in elements})
|
self.groups[name]["elements"].update({e.GlobalId: e for e in elements})
|
||||||
self.logger.info(f"Element metadata finished {time.time() - start}")
|
self.logger.info(f"Element metadata finished {time.time() - start}")
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from ..entity_instance import entity_instance
|
|||||||
|
|
||||||
from . import has_occ
|
from . import has_occ
|
||||||
|
|
||||||
from typing import TypeVar, Union, Optional, Generator, Any, Literal, overload, TYPE_CHECKING, Iterable, cast
|
from typing import TypeVar, Union, Optional, Generator, Any, Literal, overload, TYPE_CHECKING, Iterable, cast, TypedDict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from OCC.Core import TopoDS
|
from OCC.Core import TopoDS
|
||||||
@@ -409,13 +409,13 @@ class tree(ifcopenshell_wrapper.tree):
|
|||||||
set_b: Iterable[entity_instance],
|
set_b: Iterable[entity_instance],
|
||||||
tolerance: float = 0.002,
|
tolerance: float = 0.002,
|
||||||
check_all: bool = True,
|
check_all: bool = True,
|
||||||
):
|
) -> tuple[ifcopenshell_wrapper.clash, ...]:
|
||||||
args = [self, [e.wrapped_data for e in set_a], [e.wrapped_data for e in set_b], tolerance, check_all]
|
args = [self, [e.wrapped_data for e in set_a], [e.wrapped_data for e in set_b], tolerance, check_all]
|
||||||
return ifcopenshell_wrapper.tree.clash_intersection_many(*args)
|
return ifcopenshell_wrapper.tree.clash_intersection_many(*args)
|
||||||
|
|
||||||
def clash_collision_many(
|
def clash_collision_many(
|
||||||
self, set_a: Iterable[entity_instance], set_b: Iterable[entity_instance], allow_touching=False
|
self, set_a: Iterable[entity_instance], set_b: Iterable[entity_instance], allow_touching=False
|
||||||
):
|
) -> tuple[ifcopenshell_wrapper.clash, ...]:
|
||||||
args = [self, [e.wrapped_data for e in set_a], [e.wrapped_data for e in set_b], allow_touching]
|
args = [self, [e.wrapped_data for e in set_a], [e.wrapped_data for e in set_b], allow_touching]
|
||||||
return ifcopenshell_wrapper.tree.clash_collision_many(*args)
|
return ifcopenshell_wrapper.tree.clash_collision_many(*args)
|
||||||
|
|
||||||
@@ -425,7 +425,7 @@ class tree(ifcopenshell_wrapper.tree):
|
|||||||
set_b: Iterable[entity_instance],
|
set_b: Iterable[entity_instance],
|
||||||
clearance: float = 0.05,
|
clearance: float = 0.05,
|
||||||
check_all: bool = False,
|
check_all: bool = False,
|
||||||
):
|
) -> tuple[ifcopenshell_wrapper.clash, ...]:
|
||||||
args = [self, [e.wrapped_data for e in set_a], [e.wrapped_data for e in set_b], clearance, check_all]
|
args = [self, [e.wrapped_data for e in set_a], [e.wrapped_data for e in set_b], clearance, check_all]
|
||||||
return ifcopenshell_wrapper.tree.clash_clearance_many(*args)
|
return ifcopenshell_wrapper.tree.clash_clearance_many(*args)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user