mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 14:02:27 +00:00
black .
This commit is contained in:
@@ -64,8 +64,8 @@ class MaterialCreator:
|
|||||||
mesh: Union[OBJECT_DATA_TYPE, None],
|
mesh: Union[OBJECT_DATA_TYPE, None],
|
||||||
shape_has_openings: bool,
|
shape_has_openings: bool,
|
||||||
) -> None:
|
) -> None:
|
||||||
if (((rep := getattr(element, "Representation", ...)) is not ... and not rep) or
|
if ((rep := getattr(element, "Representation", ...)) is not ... and not rep) or (
|
||||||
((rep := getattr(element, "RepresentationMaps", ...)) is not ... and not rep)
|
(rep := getattr(element, "RepresentationMaps", ...)) is not ... and not rep
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -76,11 +76,7 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
view_normal = rv3d.view_rotation @ mathutils.Vector((0.0, 0.0, -1.0))
|
view_normal = rv3d.view_rotation @ mathutils.Vector((0.0, 0.0, -1.0))
|
||||||
obj_matrix = obj.matrix_world.copy()
|
obj_matrix = obj.matrix_world.copy()
|
||||||
bbox = [obj_matrix @ Vector(v) for v in obj.bound_box]
|
bbox = [obj_matrix @ Vector(v) for v in obj.bound_box]
|
||||||
bbox_edges = [
|
bbox_edges = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (3, 7)]
|
||||||
(0,1),(1,2),(2,3),(3,0),
|
|
||||||
(4,5),(5,6),(6,7),(7,4),
|
|
||||||
(0,4),(1,5),(2,6),(3,7)
|
|
||||||
]
|
|
||||||
|
|
||||||
transposed_bbox: list[Vector] = []
|
transposed_bbox: list[Vector] = []
|
||||||
bbox_2d: list[float] = []
|
bbox_2d: list[float] = []
|
||||||
@@ -116,7 +112,9 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
new_bbox = [x for x in new_bbox if x is not None]
|
new_bbox = [x for x in new_bbox if x is not None]
|
||||||
for edge in bbox_edges:
|
for edge in bbox_edges:
|
||||||
if (transposed_bbox[edge[0]] is None) ^ (transposed_bbox[edge[1]] is None):
|
if (transposed_bbox[edge[0]] is None) ^ (transposed_bbox[edge[1]] is None):
|
||||||
point, _ = cls.intersect_edge_region_border(context.region, context.space_data, rv3d, bbox[edge[0]], bbox[edge[1]])
|
point, _ = cls.intersect_edge_region_border(
|
||||||
|
context.region, context.space_data, rv3d, bbox[edge[0]], bbox[edge[1]]
|
||||||
|
)
|
||||||
if point:
|
if point:
|
||||||
new_bbox.append(point)
|
new_bbox.append(point)
|
||||||
if new_bbox:
|
if new_bbox:
|
||||||
@@ -149,7 +147,7 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
z_near = -clip_start
|
z_near = -clip_start
|
||||||
za = a_view.z
|
za = a_view.z
|
||||||
zb = b_view.z
|
zb = b_view.z
|
||||||
denom = (zb - za)
|
denom = zb - za
|
||||||
if denom == 0.0:
|
if denom == 0.0:
|
||||||
return None, None
|
return None, None
|
||||||
t = (z_near - za) / denom
|
t = (z_near - za) / denom
|
||||||
@@ -212,10 +210,7 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
final_t = initial_t
|
final_t = initial_t
|
||||||
else:
|
else:
|
||||||
found_world, found_2d, found_t = find_nearby_onscreen_point(
|
found_world, found_2d, found_t = find_nearby_onscreen_point(
|
||||||
region, rv3d,
|
region, rv3d, onscreen_vert, offscreen_vert, t_on_ab, max_iters=600, step=0.01
|
||||||
onscreen_vert, offscreen_vert,
|
|
||||||
t_on_ab,
|
|
||||||
max_iters=600, step=0.01
|
|
||||||
)
|
)
|
||||||
if found_world is None:
|
if found_world is None:
|
||||||
if init_2d is None:
|
if init_2d is None:
|
||||||
@@ -823,8 +818,8 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
hit = None
|
hit = None
|
||||||
|
|
||||||
for snap_obj in objs_to_raycast:
|
for snap_obj in objs_to_raycast:
|
||||||
if (snap_obj.obj.type in {"EMPTY", "CURVE"}
|
if snap_obj.obj.type in {"EMPTY", "CURVE"} or (
|
||||||
or (hasattr(snap_obj.obj.data, "polygons") and len(snap_obj.obj.data.polygons) == 0)
|
hasattr(snap_obj.obj.data, "polygons") and len(snap_obj.obj.data.polygons) == 0
|
||||||
):
|
):
|
||||||
# For wireframe objects we have to test all the snaps to see which is closer
|
# For wireframe objects we have to test all the snaps to see which is closer
|
||||||
snap_points = tool.Raycast.ray_cast_by_proximity_2d(context, event, snap_obj)
|
snap_points = tool.Raycast.ray_cast_by_proximity_2d(context, event, snap_obj)
|
||||||
@@ -846,7 +841,6 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
hit = closest_wf_point["point"]
|
hit = closest_wf_point["point"]
|
||||||
face_index = None
|
face_index = None
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Solid objects
|
# Solid objects
|
||||||
hit_obj, hit, face_index = cls.cast_rays_to_single_object(context, event, snap_obj.obj)
|
hit_obj, hit, face_index = cls.cast_rays_to_single_object(context, event, snap_obj.obj)
|
||||||
@@ -862,7 +856,6 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
}
|
}
|
||||||
closest_snaps.append(snap_point)
|
closest_snaps.append(snap_point)
|
||||||
|
|
||||||
|
|
||||||
# Here we test which is closer, including wireframe and solid objects
|
# Here we test which is closer, including wireframe and solid objects
|
||||||
if hit is not None:
|
if hit is not None:
|
||||||
length_squared = (hit - ray_origin).length_squared
|
length_squared = (hit - ray_origin).length_squared
|
||||||
|
|||||||
@@ -360,7 +360,6 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
plane_normal = tool.Polyline.use_transform_orientations(plane_normal)
|
plane_normal = tool.Polyline.use_transform_orientations(plane_normal)
|
||||||
return plane_origin, plane_normal
|
return plane_origin, plane_normal
|
||||||
|
|
||||||
|
|
||||||
# Polyline
|
# Polyline
|
||||||
polyline_props = tool.Model.get_polyline_props()
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
try:
|
try:
|
||||||
@@ -392,7 +391,9 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
closest_snaps = tool.Raycast.ray_cast_and_get_closest_to_camera_snaps(context, event, objs_to_raycast)
|
closest_snaps = tool.Raycast.ray_cast_and_get_closest_to_camera_snaps(context, event, objs_to_raycast)
|
||||||
detected_snaps.extend(closest_snaps)
|
detected_snaps.extend(closest_snaps)
|
||||||
|
|
||||||
xray_mode = (space.shading.type == "SOLID" and space.shading.show_xray) or (space.shading.type == "WIREFRAME" and space.shading.show_xray_wireframe)
|
xray_mode = (space.shading.type == "SOLID" and space.shading.show_xray) or (
|
||||||
|
space.shading.type == "WIREFRAME" and space.shading.show_xray_wireframe
|
||||||
|
)
|
||||||
|
|
||||||
for snap_obj in objs_to_raycast:
|
for snap_obj in objs_to_raycast:
|
||||||
for snap in closest_snaps:
|
for snap in closest_snaps:
|
||||||
@@ -405,8 +406,12 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
detected_snaps.append(point)
|
detected_snaps.append(point)
|
||||||
else:
|
else:
|
||||||
# If it is a solid object that is closest to camera it ignores all the rest
|
# If it is a solid object that is closest to camera it ignores all the rest
|
||||||
if "is_closest_to_camera" in snap and snap["is_closest_to_camera"] and snap["group"] == "Object":
|
if (
|
||||||
closest_snap = [snap] # discards objects that aren't the closest
|
"is_closest_to_camera" in snap
|
||||||
|
and snap["is_closest_to_camera"]
|
||||||
|
and snap["group"] == "Object"
|
||||||
|
):
|
||||||
|
closest_snap = [snap] # discards objects that aren't the closest
|
||||||
if "face_index" in snap and snap["face_index"] is not None:
|
if "face_index" in snap and snap["face_index"] is not None:
|
||||||
snap_points = tool.Raycast.ray_cast_by_proximity_2d(context, event, snap_obj)
|
snap_points = tool.Raycast.ray_cast_by_proximity_2d(context, event, snap_obj)
|
||||||
for point in snap_points:
|
for point in snap_points:
|
||||||
|
|||||||
@@ -997,9 +997,7 @@ class Spatial(bonsai.core.tool.Spatial):
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_obj_origin_to_polygon_center(
|
def set_obj_origin_to_polygon_center(cls, obj: bpy.types.Object, poly: Polygon, polygon_is_si: bool = True) -> None:
|
||||||
cls, obj: bpy.types.Object, poly: Polygon, polygon_is_si: bool = True
|
|
||||||
) -> None:
|
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
centroid = poly.centroid
|
centroid = poly.centroid
|
||||||
if polygon_is_si:
|
if polygon_is_si:
|
||||||
@@ -1007,7 +1005,6 @@ class Spatial(bonsai.core.tool.Spatial):
|
|||||||
else:
|
else:
|
||||||
obj.location = Vector((centroid.x * unit_scale, centroid.y * unit_scale, 0))
|
obj.location = Vector((centroid.x * unit_scale, centroid.y * unit_scale, 0))
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_2d_vertices_from_polygon(
|
def get_2d_vertices_from_polygon(
|
||||||
cls,
|
cls,
|
||||||
@@ -1195,7 +1192,6 @@ class Spatial(bonsai.core.tool.Spatial):
|
|||||||
) -> None:
|
) -> None:
|
||||||
bonsai.core.type.assign_type(ifc, tool.Model, type, element=element, type=relating_type)
|
bonsai.core.type.assign_type(ifc, tool.Model, type, element=element, type=relating_type)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_space_visibility(cls, is_visible: bool) -> None:
|
def set_space_visibility(cls, is_visible: bool) -> None:
|
||||||
if tool.Ifc.get().schema == "IFC2X3":
|
if tool.Ifc.get().schema == "IFC2X3":
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ class TestRunForeach:
|
|||||||
|
|
||||||
def test_rename_single(self, model):
|
def test_rename_single(self, model):
|
||||||
items = self._items(model, "IfcWall")
|
items = self._items(model, "IfcWall")
|
||||||
result = run_foreach(model, "attribute", "edit_attributes", {"product": "{id}", "attributes": '{"Name": "R"}'}, items)
|
result = run_foreach(
|
||||||
|
model, "attribute", "edit_attributes", {"product": "{id}", "attributes": '{"Name": "R"}'}, items
|
||||||
|
)
|
||||||
assert result["ok"] is True
|
assert result["ok"] is True
|
||||||
assert result["count"] == 1
|
assert result["count"] == 1
|
||||||
assert result["errors"] == []
|
assert result["errors"] == []
|
||||||
@@ -44,7 +46,9 @@ class TestRunForeach:
|
|||||||
|
|
||||||
def test_rename_multiple(self, model):
|
def test_rename_multiple(self, model):
|
||||||
items = self._items(model, "IfcElement")
|
items = self._items(model, "IfcElement")
|
||||||
result = run_foreach(model, "attribute", "edit_attributes", {"product": "{id}", "attributes": '{"Name": "X"}'}, items)
|
result = run_foreach(
|
||||||
|
model, "attribute", "edit_attributes", {"product": "{id}", "attributes": '{"Name": "X"}'}, items
|
||||||
|
)
|
||||||
assert result["ok"] is True
|
assert result["ok"] is True
|
||||||
assert result["count"] == len(items)
|
assert result["count"] == len(items)
|
||||||
|
|
||||||
@@ -73,7 +77,9 @@ class TestRunForeach:
|
|||||||
{"id": wall_id, "type": "IfcWall", "name": "W"},
|
{"id": wall_id, "type": "IfcWall", "name": "W"},
|
||||||
{"id": 999999, "type": "IfcWall", "name": "Bad"},
|
{"id": 999999, "type": "IfcWall", "name": "Bad"},
|
||||||
]
|
]
|
||||||
result = run_foreach(model, "attribute", "edit_attributes", {"product": "{id}", "attributes": '{"Name": "Ok"}'}, items)
|
result = run_foreach(
|
||||||
|
model, "attribute", "edit_attributes", {"product": "{id}", "attributes": '{"Name": "Ok"}'}, items
|
||||||
|
)
|
||||||
assert result["ok"] is False
|
assert result["ok"] is False
|
||||||
assert result["count"] == 1
|
assert result["count"] == 1
|
||||||
assert len(result["errors"]) == 1
|
assert len(result["errors"]) == 1
|
||||||
|
|||||||
@@ -111,8 +111,13 @@ class TestForeachCommand:
|
|||||||
def test_foreach_rename(self, model, model_file):
|
def test_foreach_rename(self, model, model_file):
|
||||||
walls_json = self._select_json(model, "IfcWall")
|
walls_json = self._select_json(model, "IfcWall")
|
||||||
stdout, stderr, rc = run_ifcedit(
|
stdout, stderr, rc = run_ifcedit(
|
||||||
"foreach", model_file, "attribute.edit_attributes",
|
"foreach",
|
||||||
"--product", "{id}", "--attributes", '{"Name": "Renamed"}',
|
model_file,
|
||||||
|
"attribute.edit_attributes",
|
||||||
|
"--product",
|
||||||
|
"{id}",
|
||||||
|
"--attributes",
|
||||||
|
'{"Name": "Renamed"}',
|
||||||
stdin=walls_json,
|
stdin=walls_json,
|
||||||
)
|
)
|
||||||
assert rc == 0, f"stderr: {stderr}"
|
assert rc == 0, f"stderr: {stderr}"
|
||||||
@@ -129,8 +134,13 @@ class TestForeachCommand:
|
|||||||
items = json.loads(elements_json)
|
items = json.loads(elements_json)
|
||||||
assert len(items) >= 2
|
assert len(items) >= 2
|
||||||
stdout, stderr, rc = run_ifcedit(
|
stdout, stderr, rc = run_ifcedit(
|
||||||
"foreach", model_file, "attribute.edit_attributes",
|
"foreach",
|
||||||
"--product", "{id}", "--attributes", '{"Name": "Bulk"}',
|
model_file,
|
||||||
|
"attribute.edit_attributes",
|
||||||
|
"--product",
|
||||||
|
"{id}",
|
||||||
|
"--attributes",
|
||||||
|
'{"Name": "Bulk"}',
|
||||||
stdin=elements_json,
|
stdin=elements_json,
|
||||||
)
|
)
|
||||||
assert rc == 0, f"stderr: {stderr}"
|
assert rc == 0, f"stderr: {stderr}"
|
||||||
@@ -140,8 +150,13 @@ class TestForeachCommand:
|
|||||||
|
|
||||||
def test_foreach_empty_list(self, model_file):
|
def test_foreach_empty_list(self, model_file):
|
||||||
stdout, stderr, rc = run_ifcedit(
|
stdout, stderr, rc = run_ifcedit(
|
||||||
"foreach", model_file, "attribute.edit_attributes",
|
"foreach",
|
||||||
"--product", "{id}", "--attributes", '{"Name": "X"}',
|
model_file,
|
||||||
|
"attribute.edit_attributes",
|
||||||
|
"--product",
|
||||||
|
"{id}",
|
||||||
|
"--attributes",
|
||||||
|
'{"Name": "X"}',
|
||||||
stdin="[]",
|
stdin="[]",
|
||||||
)
|
)
|
||||||
assert rc == 0
|
assert rc == 0
|
||||||
@@ -151,7 +166,11 @@ class TestForeachCommand:
|
|||||||
|
|
||||||
def test_foreach_invalid_json_stdin(self, model_file):
|
def test_foreach_invalid_json_stdin(self, model_file):
|
||||||
stdout, stderr, rc = run_ifcedit(
|
stdout, stderr, rc = run_ifcedit(
|
||||||
"foreach", model_file, "root.remove_product", "--product", "{id}",
|
"foreach",
|
||||||
|
model_file,
|
||||||
|
"root.remove_product",
|
||||||
|
"--product",
|
||||||
|
"{id}",
|
||||||
stdin="not json",
|
stdin="not json",
|
||||||
)
|
)
|
||||||
assert rc != 0
|
assert rc != 0
|
||||||
@@ -159,7 +178,11 @@ class TestForeachCommand:
|
|||||||
|
|
||||||
def test_foreach_not_array_stdin(self, model_file):
|
def test_foreach_not_array_stdin(self, model_file):
|
||||||
stdout, stderr, rc = run_ifcedit(
|
stdout, stderr, rc = run_ifcedit(
|
||||||
"foreach", model_file, "root.remove_product", "--product", "{id}",
|
"foreach",
|
||||||
|
model_file,
|
||||||
|
"root.remove_product",
|
||||||
|
"--product",
|
||||||
|
"{id}",
|
||||||
stdin='{"id": 1}',
|
stdin='{"id": 1}',
|
||||||
)
|
)
|
||||||
assert rc != 0
|
assert rc != 0
|
||||||
@@ -167,12 +190,19 @@ class TestForeachCommand:
|
|||||||
|
|
||||||
def test_foreach_output_to_different_file(self, model, model_file, tmp_path):
|
def test_foreach_output_to_different_file(self, model, model_file, tmp_path):
|
||||||
import os
|
import os
|
||||||
|
|
||||||
output = str(tmp_path / "out.ifc")
|
output = str(tmp_path / "out.ifc")
|
||||||
walls_json = self._select_json(model, "IfcWall")
|
walls_json = self._select_json(model, "IfcWall")
|
||||||
stdout, stderr, rc = run_ifcedit(
|
stdout, stderr, rc = run_ifcedit(
|
||||||
"foreach", model_file, "attribute.edit_attributes",
|
"foreach",
|
||||||
"-o", output,
|
model_file,
|
||||||
"--product", "{id}", "--attributes", '{"Name": "OutFile"}',
|
"attribute.edit_attributes",
|
||||||
|
"-o",
|
||||||
|
output,
|
||||||
|
"--product",
|
||||||
|
"{id}",
|
||||||
|
"--attributes",
|
||||||
|
'{"Name": "OutFile"}',
|
||||||
stdin=walls_json,
|
stdin=walls_json,
|
||||||
)
|
)
|
||||||
assert rc == 0, f"stderr: {stderr}"
|
assert rc == 0, f"stderr: {stderr}"
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ def main():
|
|||||||
from mcp.server.fastmcp import FastMCP # noqa: F401
|
from mcp.server.fastmcp import FastMCP # noqa: F401
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
print(
|
print(
|
||||||
"error: the 'mcp' package is required to run the server.\n"
|
"error: the 'mcp' package is required to run the server.\n" "Install it with: pip install mcp",
|
||||||
"Install it with: pip install mcp",
|
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
@@ -137,7 +137,11 @@ def open(
|
|||||||
def open(path: Union[os.PathLike, str], format: SupportedFormat = None, *, should_stream: Literal[True]) -> _stream: ...
|
def open(path: Union[os.PathLike, str], format: SupportedFormat = None, *, should_stream: Literal[True]) -> _stream: ...
|
||||||
@overload
|
@overload
|
||||||
def open(
|
def open(
|
||||||
path: Union[os.PathLike, str], format: SupportedFormat = None, *, should_stream: bool = False, readonly: bool = False
|
path: Union[os.PathLike, str],
|
||||||
|
format: SupportedFormat = None,
|
||||||
|
*,
|
||||||
|
should_stream: bool = False,
|
||||||
|
readonly: bool = False,
|
||||||
) -> Union[_file, sqlite, _stream]: ...
|
) -> Union[_file, sqlite, _stream]: ...
|
||||||
def open(
|
def open(
|
||||||
path: Union[os.PathLike, str],
|
path: Union[os.PathLike, str],
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ from typing import Optional
|
|||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
|
||||||
|
|
||||||
_ITEM_TYPE_TO_REP_TYPE = {
|
_ITEM_TYPE_TO_REP_TYPE = {
|
||||||
"IfcVertex": "Vertex",
|
"IfcVertex": "Vertex",
|
||||||
"IfcVertexPoint": "Vertex",
|
"IfcVertexPoint": "Vertex",
|
||||||
|
|||||||
@@ -62,9 +62,7 @@ class TestEditCostValue(test.bootstrap.IFC4):
|
|||||||
attributes={"UnitBasis": {"ValueComponent": 1.0, "UnitComponent": unit}},
|
attributes={"UnitBasis": {"ValueComponent": 1.0, "UnitComponent": unit}},
|
||||||
)
|
)
|
||||||
assert value.UnitBasis is not None
|
assert value.UnitBasis is not None
|
||||||
ifcopenshell.api.cost.edit_cost_value(
|
ifcopenshell.api.cost.edit_cost_value(self.file, cost_value=value, attributes={"UnitBasis": None})
|
||||||
self.file, cost_value=value, attributes={"UnitBasis": None}
|
|
||||||
)
|
|
||||||
assert value.UnitBasis is None
|
assert value.UnitBasis is None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,18 @@ class TestAddGeoreferencing(test.bootstrap.IFC4):
|
|||||||
def test_recovering_from_orphan_coordinate_operation(self):
|
def test_recovering_from_orphan_coordinate_operation(self):
|
||||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||||
context = ifcopenshell.api.context.add_context(self.file, "Model")
|
context = ifcopenshell.api.context.add_context(self.file, "Model")
|
||||||
self.file.create_entity("IfcMapConversion", SourceCRS=context, TargetCRS=self.file.create_entity("IfcProjectedCRS", Name="EPSG:1234"))
|
self.file.create_entity(
|
||||||
|
"IfcMapConversion",
|
||||||
|
SourceCRS=context,
|
||||||
|
TargetCRS=self.file.create_entity("IfcProjectedCRS", Name="EPSG:1234"),
|
||||||
|
)
|
||||||
ifcopenshell.api.georeference.remove_georeferencing(self.file)
|
ifcopenshell.api.georeference.remove_georeferencing(self.file)
|
||||||
# Simulate orphan by re-adding just a conversion without CRS
|
# Simulate orphan by re-adding just a conversion without CRS
|
||||||
self.file.create_entity("IfcMapConversion", SourceCRS=context, TargetCRS=self.file.create_entity("IfcProjectedCRS", Name="EPSG:1234"))
|
self.file.create_entity(
|
||||||
|
"IfcMapConversion",
|
||||||
|
SourceCRS=context,
|
||||||
|
TargetCRS=self.file.create_entity("IfcProjectedCRS", Name="EPSG:1234"),
|
||||||
|
)
|
||||||
self.file.remove(self.file.by_type("IfcProjectedCRS")[0])
|
self.file.remove(self.file.by_type("IfcProjectedCRS")[0])
|
||||||
assert len(self.file.by_type("IfcProjectedCRS")) == 0
|
assert len(self.file.by_type("IfcProjectedCRS")) == 0
|
||||||
assert len(self.file.by_type("IfcCoordinateOperation")) == 1
|
assert len(self.file.by_type("IfcCoordinateOperation")) == 1
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ class TestRemoveResourceQuantity(test.bootstrap.IFC4):
|
|||||||
def test_removing_a_resource_quantity(self):
|
def test_removing_a_resource_quantity(self):
|
||||||
self.file.create_entity("IfcProject")
|
self.file.create_entity("IfcProject")
|
||||||
resource = ifcopenshell.api.resource.add_resource(self.file, ifc_class="IfcLaborResource")
|
resource = ifcopenshell.api.resource.add_resource(self.file, ifc_class="IfcLaborResource")
|
||||||
ifcopenshell.api.resource.add_resource_quantity(
|
ifcopenshell.api.resource.add_resource_quantity(self.file, resource=resource, ifc_class="IfcQuantityTime")
|
||||||
self.file, resource=resource, ifc_class="IfcQuantityTime"
|
|
||||||
)
|
|
||||||
assert resource.BaseQuantity is not None
|
assert resource.BaseQuantity is not None
|
||||||
ifcopenshell.api.resource.remove_resource_quantity(self.file, resource=resource)
|
ifcopenshell.api.resource.remove_resource_quantity(self.file, resource=resource)
|
||||||
assert resource.BaseQuantity is None
|
assert resource.BaseQuantity is None
|
||||||
|
|||||||
@@ -167,7 +167,11 @@ def _collect_elements(data: Any, seen: set[int], result: list[dict[str, Any]]) -
|
|||||||
eid = data["id"]
|
eid = data["id"]
|
||||||
if eid not in seen:
|
if eid not in seen:
|
||||||
seen.add(eid)
|
seen.add(eid)
|
||||||
result.append({"id": data["id"], "type": data.get("type"), "name": data.get("name")} if "name" in data else {"id": data["id"], "type": data.get("type")})
|
result.append(
|
||||||
|
{"id": data["id"], "type": data.get("type"), "name": data.get("name")}
|
||||||
|
if "name" in data
|
||||||
|
else {"id": data["id"], "type": data.get("type")}
|
||||||
|
)
|
||||||
for v in data.values():
|
for v in data.values():
|
||||||
_collect_elements(v, seen, result)
|
_collect_elements(v, seen, result)
|
||||||
elif isinstance(data, list):
|
elif isinstance(data, list):
|
||||||
|
|||||||
Reference in New Issue
Block a user