mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 06:09:16 +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:
|
try:
|
||||||
core.generate_space(tool.Ifc, tool.Model, tool.Root, tool.Spatial, tool.Type)
|
core.generate_space(tool.Ifc, tool.Model, tool.Root, tool.Spatial, tool.Type)
|
||||||
except core.NoDefaultContainer:
|
except core.SpaceGenerationError as e:
|
||||||
return self.report({"ERROR"}, "Please set a default container to create the space in.")
|
return self.report({"ERROR"}, str(e))
|
||||||
|
|
||||||
|
|
||||||
class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
|
class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
|
|||||||
@@ -156,8 +156,8 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
bonsai.core.spatial.generate_space(tool.Ifc, tool.Model, tool.Root, tool.Spatial, tool.Type)
|
bonsai.core.spatial.generate_space(tool.Ifc, tool.Model, tool.Root, tool.Spatial, tool.Type)
|
||||||
except bonsai.core.spatial.NoDefaultContainer:
|
except bonsai.core.spatial.SpaceGenerationError as e:
|
||||||
return self.report({"ERROR"}, "Please set a default container to create the space in.")
|
return self.report({"ERROR"}, str(e))
|
||||||
|
|
||||||
def hotkey_S_B(self):
|
def hotkey_S_B(self):
|
||||||
bpy.ops.bim.add_boundary()
|
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)
|
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||||
|
|
||||||
if not space_polygon:
|
if isinstance(space_polygon, str):
|
||||||
return
|
return
|
||||||
|
|
||||||
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0)
|
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)
|
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||||
|
|
||||||
if not space_polygon:
|
if isinstance(space_polygon, str):
|
||||||
return
|
return
|
||||||
|
|
||||||
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0)
|
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)
|
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||||
|
|
||||||
if not space_polygon:
|
if isinstance(space_polygon, str):
|
||||||
return
|
return
|
||||||
|
|
||||||
bm = spatial.get_bmesh_from_polygon(space_polygon, h=0)
|
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/>.
|
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import TYPE_CHECKING, Optional, Union
|
from typing import TYPE_CHECKING, Optional, Union, assert_never
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import bpy
|
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))
|
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():
|
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()
|
active_obj = spatial.get_active_obj()
|
||||||
selected_objects = spatial.get_selected_objects()
|
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)
|
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||||
|
|
||||||
if not space_polygon:
|
if isinstance(space_polygon, str):
|
||||||
return
|
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)
|
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)
|
spatial.set_default_container(container)
|
||||||
|
|
||||||
|
|
||||||
class NoDefaultContainer(Exception):
|
class SpaceGenerationError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -628,14 +628,20 @@ class Spatial(bonsai.core.tool.Spatial):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@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()
|
boundary_lines = cls.get_boundary_lines_from_context_visible_objects()
|
||||||
unioned_boundaries = shapely.union_all(shapely.GeometryCollection(boundary_lines))
|
unioned_boundaries = shapely.union_all(shapely.GeometryCollection(boundary_lines))
|
||||||
closed_polygons = shapely.polygonize(unioned_boundaries.geoms)
|
closed_polygons = shapely.polygonize(unioned_boundaries.geoms)
|
||||||
|
if not closed_polygons:
|
||||||
|
return "NO POLYGONS FOUND"
|
||||||
space_polygon = None
|
space_polygon = None
|
||||||
for polygon in closed_polygons.geoms:
|
for polygon in closed_polygons.geoms:
|
||||||
if shapely.contains_xy(polygon, x, y):
|
if shapely.contains_xy(polygon, x, y):
|
||||||
space_polygon = shapely.force_3d(polygon)
|
space_polygon = shapely.force_3d(polygon)
|
||||||
|
if space_polygon is None:
|
||||||
|
return "NO POLYGON FOR POINT"
|
||||||
return space_polygon
|
return space_polygon
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
Reference in New Issue
Block a user