layer.assign_layer - support batching #4474

This commit is contained in:
Andrej730
2024-04-08 14:30:30 +05:00
parent f34aef1ebf
commit 7ecec973dd
6 changed files with 68 additions and 20 deletions
@@ -151,7 +151,10 @@ class AssignPresentationLayer(bpy.types.Operator):
ifcopenshell.api.run( ifcopenshell.api.run(
"layer.assign_layer", "layer.assign_layer",
self.file, self.file,
**{"item": self.file.by_id(item.BIMMeshProperties.ifc_definition_id), "layer": self.file.by_id(self.layer)} **{
"items": [self.file.by_id(item.BIMMeshProperties.ifc_definition_id)],
"layer": self.file.by_id(self.layer),
}
) )
return {"FINISHED"} return {"FINISHED"}
@@ -20,8 +20,10 @@ import ifcopenshell
class Usecase: class Usecase:
def __init__(self, file, item=None, layer=None): def __init__(
"""Assigns a representation item to a layer self, file: ifcopenshell.file, items: list[ifcopenshell.entity_instance], layer: ifcopenshell.entity_instance
):
"""Assigns representation items to a layer
In IFC, instead of objects being assigned to layers, representation In IFC, instead of objects being assigned to layers, representation
items are assigned to layers. Representation items are portions of the items are assigned to layers. Representation items are portions of the
@@ -30,9 +32,9 @@ class Usecase:
its frame) assigned to one layer, and another portion (e.g. the glazing its frame) assigned to one layer, and another portion (e.g. the glazing
panels) assigned to another layer. panels) assigned to another layer.
:param item: The IfcRepresentationItem to assign to the layer. This :param items: The list of IfcRepresentationItems to assign to the layer. This
should be one of the items in the object's IfcShapeRepresentation. should be the items from the object's IfcShapeRepresentation.
:type item: ifcopenshell.entity_instance.entity_instance :type items: list[ifcopenshell.entity_instance.entity_instance]
:param layer: The IfcPresentationLayerAssignment layer to assign the :param layer: The IfcPresentationLayerAssignment layer to assign the
item to. item to.
:type layer: ifcopenshell.entity_instance.entity_instance :type layer: ifcopenshell.entity_instance.entity_instance
@@ -62,15 +64,19 @@ class Usecase:
# And assign our wall representation item (in this example, there is # And assign our wall representation item (in this example, there is
# only one item) to the layer. # only one item) to the layer.
ifcopenshell.api.run("layer.assign_layer", model, item=representation.Items[0], layer=layer) ifcopenshell.api.run("layer.assign_layer", model, items=[representation.Items[0]], layer=layer)
""" """
self.file = file self.file = file
self.settings = { self.settings = {
"item": item, "items": items,
"layer": layer, "layer": layer,
} }
def execute(self): def execute(self) -> None:
assigned_items = set(self.settings["layer"].AssignedItems or []) # support AssignedItems == None since layer might just got created
assigned_items.add(self.settings["item"]) layer = self.settings["layer"]
self.settings["layer"].AssignedItems = list(assigned_items) assigned_items = set(layer.AssignedItems or [])
items = set(self.settings["items"])
if items.issubset(assigned_items):
return
layer.AssignedItems = list(assigned_items | items)
@@ -54,7 +54,7 @@ class Usecase:
# And assign our wall representation item (in this example, there is # And assign our wall representation item (in this example, there is
# only one item) to the layer. # only one item) to the layer.
ifcopenshell.api.run("layer.assign_layer", model, item=representation.Items[0], layer=layer) ifcopenshell.api.run("layer.assign_layer", model, items=[representation.Items[0]], layer=layer)
# Let's undo it! # Let's undo it!
ifcopenshell.api.run("layer.unassign_layer", model, item=representation.Items[0], layer=layer) ifcopenshell.api.run("layer.unassign_layer", model, item=representation.Items[0], layer=layer)
@@ -0,0 +1,39 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import test.bootstrap
import ifcopenshell.api
class TestAssignLayer(test.bootstrap.IFC4):
def test_assign_layer_to_items(self):
items = [self.file.createIfcExtrudedAreaSolid() for i in range(2)]
layer = self.file.createIfcPresentationLayerAssignment()
ifcopenshell.api.run("layer.assign_layer", self.file, items=items, layer=layer)
assert len(layer.AssignedItems) == 2
assert set(layer.AssignedItems) == set(items)
def test_assign_additional_items(self):
items = [self.file.createIfcExtrudedAreaSolid() for i in range(4)]
layer = self.file.createIfcPresentationLayerAssignment()
ifcopenshell.api.run("layer.assign_layer", self.file, items=items[:2], layer=layer)
ifcopenshell.api.run("layer.assign_layer", self.file, items=items[2:], layer=layer)
assert len(layer.AssignedItems) == 4
assert set(layer.AssignedItems) == set(items)
@@ -634,7 +634,7 @@ class TestGetElementsByLayer(test.bootstrap.IFC4):
layer = ifcopenshell.api.run("layer.add_layer", self.file) layer = ifcopenshell.api.run("layer.add_layer", self.file)
representation = self.file.createIfcShapeRepresentation() representation = self.file.createIfcShapeRepresentation()
element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation]) element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation])
ifcopenshell.api.run("layer.assign_layer", self.file, item=representation, layer=layer) ifcopenshell.api.run("layer.assign_layer", self.file, items=[representation], layer=layer)
assert list(subject.get_elements_by_layer(self.file, layer)) == [element] assert list(subject.get_elements_by_layer(self.file, layer)) == [element]
@@ -644,7 +644,7 @@ class TestGetlayers(test.bootstrap.IFC4):
layer = ifcopenshell.api.run("layer.add_layer", self.file) layer = ifcopenshell.api.run("layer.add_layer", self.file)
representation = self.file.createIfcShapeRepresentation() representation = self.file.createIfcShapeRepresentation()
element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation]) element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation])
ifcopenshell.api.run("layer.assign_layer", self.file, item=representation, layer=layer) ifcopenshell.api.run("layer.assign_layer", self.file, items=[representation], layer=layer)
assert subject.get_layers(self.file, element) == [layer] assert subject.get_layers(self.file, element) == [layer]
def test_getting_the_layer_of_a_product_item(self): def test_getting_the_layer_of_a_product_item(self):
@@ -653,7 +653,7 @@ class TestGetlayers(test.bootstrap.IFC4):
item = self.file.createIfcExtrudedAreaSolid() item = self.file.createIfcExtrudedAreaSolid()
representation = self.file.createIfcShapeRepresentation(Items=[item]) representation = self.file.createIfcShapeRepresentation(Items=[item])
element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation]) element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation])
ifcopenshell.api.run("layer.assign_layer", self.file, item=item, layer=layer) ifcopenshell.api.run("layer.assign_layer", self.file, items=[item], layer=layer)
assert subject.get_layers(self.file, element) == [layer] assert subject.get_layers(self.file, element) == [layer]
def test_getting_the_layer_of_a_type_product_representation(self): def test_getting_the_layer_of_a_type_product_representation(self):
@@ -661,7 +661,7 @@ class TestGetlayers(test.bootstrap.IFC4):
layer = ifcopenshell.api.run("layer.add_layer", self.file) layer = ifcopenshell.api.run("layer.add_layer", self.file)
representation = self.file.createIfcShapeRepresentation() representation = self.file.createIfcShapeRepresentation()
element.RepresentationMaps = [self.file.createIfcRepresentationMap(MappedRepresentation=representation)] element.RepresentationMaps = [self.file.createIfcRepresentationMap(MappedRepresentation=representation)]
ifcopenshell.api.run("layer.assign_layer", self.file, item=representation, layer=layer) ifcopenshell.api.run("layer.assign_layer", self.file, items=[representation], layer=layer)
assert subject.get_layers(self.file, element) == [layer] assert subject.get_layers(self.file, element) == [layer]
def test_getting_the_layer_of_a_type_product_item(self): def test_getting_the_layer_of_a_type_product_item(self):
@@ -670,7 +670,7 @@ class TestGetlayers(test.bootstrap.IFC4):
item = self.file.createIfcExtrudedAreaSolid() item = self.file.createIfcExtrudedAreaSolid()
representation = self.file.createIfcShapeRepresentation(Items=[item]) representation = self.file.createIfcShapeRepresentation(Items=[item])
element.RepresentationMaps = [self.file.createIfcRepresentationMap(MappedRepresentation=representation)] element.RepresentationMaps = [self.file.createIfcRepresentationMap(MappedRepresentation=representation)]
ifcopenshell.api.run("layer.assign_layer", self.file, item=item, layer=layer) ifcopenshell.api.run("layer.assign_layer", self.file, items=[item], layer=layer)
assert subject.get_layers(self.file, element) == [layer] assert subject.get_layers(self.file, element) == [layer]
@@ -681,7 +681,7 @@ class TestGetlayersIFC2X3(test.bootstrap.IFC2X3):
item = self.file.createIfcExtrudedAreaSolid() item = self.file.createIfcExtrudedAreaSolid()
representation = self.file.createIfcShapeRepresentation(Items=[item]) representation = self.file.createIfcShapeRepresentation(Items=[item])
element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation]) element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation])
ifcopenshell.api.run("layer.assign_layer", self.file, item=item, layer=layer) ifcopenshell.api.run("layer.assign_layer", self.file, items=[item], layer=layer)
assert subject.get_layers(self.file, element) == [layer] assert subject.get_layers(self.file, element) == [layer]
def test_getting_the_layer_of_a_type_product_item(self): def test_getting_the_layer_of_a_type_product_item(self):
@@ -690,7 +690,7 @@ class TestGetlayersIFC2X3(test.bootstrap.IFC2X3):
item = self.file.createIfcExtrudedAreaSolid() item = self.file.createIfcExtrudedAreaSolid()
representation = self.file.createIfcShapeRepresentation(Items=[item]) representation = self.file.createIfcShapeRepresentation(Items=[item])
element.RepresentationMaps = [self.file.createIfcRepresentationMap(MappedRepresentation=representation)] element.RepresentationMaps = [self.file.createIfcRepresentationMap(MappedRepresentation=representation)]
ifcopenshell.api.run("layer.assign_layer", self.file, item=item, layer=layer) ifcopenshell.api.run("layer.assign_layer", self.file, items=[item], layer=layer)
assert subject.get_layers(self.file, element) == [layer] assert subject.get_layers(self.file, element) == [layer]