bim.generate_space not to fail silently

This commit is contained in:
Andrej730
2024-10-22 15:11:58 +05:00
parent 7bebd2f7ce
commit 7544053f0b
5 changed files with 34 additions and 14 deletions
+2 -2
View File
@@ -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()
+3 -3
View File
@@ -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)
+20 -6
View File
@@ -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
+7 -1
View File
@@ -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