mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
bim.generate_space not to fail silently
This commit is contained in:
@@ -42,8 +42,8 @@ class GenerateSpace(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
try:
|
||||
core.generate_space(tool.Ifc, tool.Model, tool.Root, tool.Spatial, tool.Type)
|
||||
except core.NoDefaultContainer:
|
||||
return self.report({"ERROR"}, "Please set a default container to create the space in.")
|
||||
except core.SpaceGenerationError as e:
|
||||
return self.report({"ERROR"}, str(e))
|
||||
|
||||
|
||||
class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
@@ -156,8 +156,8 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
else:
|
||||
try:
|
||||
bonsai.core.spatial.generate_space(tool.Ifc, tool.Model, tool.Root, tool.Spatial, tool.Type)
|
||||
except bonsai.core.spatial.NoDefaultContainer:
|
||||
return self.report({"ERROR"}, "Please set a default container to create the space in.")
|
||||
except bonsai.core.spatial.SpaceGenerationError as e:
|
||||
return self.report({"ERROR"}, str(e))
|
||||
|
||||
def hotkey_S_B(self):
|
||||
bpy.ops.bim.add_boundary()
|
||||
|
||||
@@ -46,7 +46,7 @@ def add_instance_flooring_covering_from_cursor(ifc: tool.Ifc, root: tool.Root, s
|
||||
|
||||
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||
|
||||
if not space_polygon:
|
||||
if isinstance(space_polygon, str):
|
||||
return
|
||||
|
||||
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0)
|
||||
@@ -91,7 +91,7 @@ def add_instance_ceiling_covering_from_cursor(
|
||||
|
||||
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||
|
||||
if not space_polygon:
|
||||
if isinstance(space_polygon, str):
|
||||
return
|
||||
|
||||
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0)
|
||||
@@ -123,7 +123,7 @@ def regen_selected_covering_object(root: tool.Root, spatial: tool.Spatial) -> No
|
||||
|
||||
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||
|
||||
if not space_polygon:
|
||||
if isinstance(space_polygon, str):
|
||||
return
|
||||
|
||||
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
from typing import TYPE_CHECKING, Optional, Union, assert_never
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import bpy
|
||||
@@ -152,9 +152,14 @@ def select_decomposed_element(ifc: tool.Ifc, spatial: tool.Spatial, element: ifc
|
||||
spatial.set_active_object(ifc.get_object(element))
|
||||
|
||||
|
||||
def generate_space(ifc: tool.Ifc, model: tool.Model, root: tool.Root, spatial: tool.Spatial, type: tool.Type) -> None:
|
||||
def generate_space(
|
||||
ifc: tool.Ifc, model: tool.Model, root: tool.Root, spatial: tool.Spatial, type: tool.Type
|
||||
) -> Union[None, str]:
|
||||
"""
|
||||
:return: None if successful, error message string if not.
|
||||
"""
|
||||
if not root.get_default_container():
|
||||
raise NoDefaultContainer()
|
||||
raise SpaceGenerationError("Please set a default container to create the space in.")
|
||||
|
||||
active_obj = spatial.get_active_obj()
|
||||
selected_objects = spatial.get_selected_objects()
|
||||
@@ -175,8 +180,17 @@ def generate_space(ifc: tool.Ifc, model: tool.Model, root: tool.Root, spatial: t
|
||||
|
||||
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||
|
||||
if not space_polygon:
|
||||
return
|
||||
if isinstance(space_polygon, str):
|
||||
if space_polygon == "NO POLYGONS FOUND":
|
||||
raise SpaceGenerationError(
|
||||
"Couldn't find any polygons to form the space shape. Perhaps, RL value need to be adjusted."
|
||||
)
|
||||
elif space_polygon == "NO POLYGON FOR POINT":
|
||||
raise SpaceGenerationError(
|
||||
f"Couldn't find any polygons containing the position ({x}, {y}). Perhaps, RL value need to be adjusted."
|
||||
)
|
||||
else:
|
||||
assert space_polygon
|
||||
|
||||
bm = spatial.get_bmesh_from_polygon(space_polygon, h=h, polygon_is_si=True)
|
||||
|
||||
@@ -244,5 +258,5 @@ def set_default_container(spatial: tool.Spatial, container: ifcopenshell.entity_
|
||||
spatial.set_default_container(container)
|
||||
|
||||
|
||||
class NoDefaultContainer(Exception):
|
||||
class SpaceGenerationError(Exception):
|
||||
pass
|
||||
|
||||
@@ -628,14 +628,20 @@ class Spatial(bonsai.core.tool.Spatial):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def get_space_polygon_from_context_visible_objects(cls, x: float, y: float) -> Union[shapely.Polygon, None]:
|
||||
def get_space_polygon_from_context_visible_objects(
|
||||
cls, x: float, y: float
|
||||
) -> Union[shapely.Polygon, Literal["NO POLYGONS FOUND", "NO POLYGON FOR POINT"]]:
|
||||
boundary_lines = cls.get_boundary_lines_from_context_visible_objects()
|
||||
unioned_boundaries = shapely.union_all(shapely.GeometryCollection(boundary_lines))
|
||||
closed_polygons = shapely.polygonize(unioned_boundaries.geoms)
|
||||
if not closed_polygons:
|
||||
return "NO POLYGONS FOUND"
|
||||
space_polygon = None
|
||||
for polygon in closed_polygons.geoms:
|
||||
if shapely.contains_xy(polygon, x, y):
|
||||
space_polygon = shapely.force_3d(polygon)
|
||||
if space_polygon is None:
|
||||
return "NO POLYGON FOR POINT"
|
||||
return space_polygon
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user