This commit is contained in:
Andrej730
2025-02-18 15:18:23 +05:00
parent 83a351b1c7
commit 17642ca4e9
117 changed files with 683 additions and 1005 deletions
@@ -26,16 +26,14 @@ def add_metric_reference(
Adds a chain of references to a metric. The reference path is a string of the form "attribute.attribute.attribute"
Used to reference a value of an attribute of an instance through a metric objective entity.
"""
settings = {"metric": metric, "reference_path": reference_path}
references_created = []
if settings["reference_path"]:
attributes = settings["reference_path"].split(".")
if reference_path:
attributes = reference_path.split(".")
for i in range(len(attributes)):
if i == 0:
reference = file.create_entity("IfcReference")
reference.AttributeIdentifier = attributes[i]
settings["metric"].ReferencePath = reference
metric.ReferencePath = reference
references_created.append(reference)
else:
reference = file.create_entity("IfcReference")
@@ -39,36 +39,29 @@ def assign_constraint(
:param products: The list of products the constraint applies to. This is anything
which can have properties or quantities.
:type products: list[ifcopenshell.entity_instance]
:param constraint: The IfcObjective constraint
:type constraint: ifcopenshell.entity_instance
:return: The new or updated IfcRelAssociatesConstraint relationship
or `None` if `products` was an empty list.
:rtype: ifcopenshell.entity_instance
"""
usecase = Usecase()
usecase.file = file
usecase.settings = {
"products": products,
"constraint": constraint,
}
return usecase.execute()
return usecase.execute(products, constraint)
class Usecase:
def execute(self):
products = set(self.settings["products"])
file: ifcopenshell.file
def execute(self, products: list[ifcopenshell.entity_instance], constraint: ifcopenshell.entity_instance):
if not products:
return
products_set = set(products)
self.constraint = self.settings["constraint"]
rels = self.get_constraint_rels()
rels = self.get_constraint_rels(constraint)
related_objects = set()
for rel in rels:
related_objects.update(rel.RelatedObjects)
products_to_assign = products - related_objects
products_to_assign = products_set - related_objects
if not products_to_assign:
return rels[0]
@@ -85,14 +78,14 @@ class Usecase:
**{
"GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(self.file),
"RelatingConstraint": self.constraint,
"RelatingConstraint": constraint,
"RelatedObjects": list(products_to_assign),
}
)
def get_constraint_rels(self) -> list[ifcopenshell.entity_instance]:
def get_constraint_rels(self, constraint: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
rels = []
for rel in self.file.get_inverse(self.constraint):
for rel in self.file.get_inverse(constraint):
if rel.is_a("IfcRelAssociatesConstraint"):
rels.append(rel)
return rels
@@ -26,11 +26,8 @@ def edit_metric(file: ifcopenshell.file, metric: ifcopenshell.entity_instance, a
IfcMetric, consult the IFC documentation.
:param metric: The IfcMetric you want to edit.
:type metric: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict
:return: None
:rtype: None
Example:
@@ -42,7 +39,5 @@ def edit_metric(file: ifcopenshell.file, metric: ifcopenshell.entity_instance, a
ifcopenshell.api.constraint.edit_metric(model,
metric=metric, attributes={"ConstraintGrade": "HARD"})
"""
settings = {"metric": metric, "attributes": attributes or {}}
for name, value in settings["attributes"].items():
setattr(settings["metric"], name, value)
for name, value in attributes.items():
setattr(metric, name, value)
@@ -28,11 +28,8 @@ def edit_objective(
IfcObjective, consult the IFC documentation.
:param objective: The IfcObjective you want to edit.
:type objective: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict
:return: None
:rtype: None
Example:
@@ -42,7 +39,5 @@ def edit_objective(
ifcopenshell.api.constraint.edit_objective(model,
objective=objective, attributes={"ConstraintGrade": "HARD"})
"""
settings = {"objective": objective, "attributes": attributes or {}}
for name, value in settings["attributes"].items():
setattr(settings["objective"], name, value)
for name, value in attributes.items():
setattr(objective, name, value)
@@ -16,6 +16,7 @@
# 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 ifcopenshell
import ifcopenshell.util.element
def remove_metric(file: ifcopenshell.file, metric: ifcopenshell.entity_instance) -> None:
@@ -41,17 +42,18 @@ def remove_metric(file: ifcopenshell.file, metric: ifcopenshell.entity_instance)
"""
usecase = Usecase()
usecase.file = file
usecase.settings = {"metric": metric}
return usecase.execute()
return usecase.execute(metric)
class Usecase:
def execute(self):
if self.settings["metric"].ReferencePath:
reference = self.settings["metric"].ReferencePath
file: ifcopenshell.file
def execute(self, metric: ifcopenshell.entity_instance) -> None:
if metric.ReferencePath:
reference = metric.ReferencePath
self.delete_reference(reference)
self.file.remove(self.settings["metric"])
self.file.remove(metric)
for rel in self.file.by_type("IfcRelAssociatesConstraint"):
if not rel.RelatingConstraint:
history = rel.OwnerHistory
@@ -62,7 +64,7 @@ class Usecase:
if not resource_rel.RelatingConstraint:
self.file.remove(resource_rel)
def delete_reference(self, reference):
def delete_reference(self, reference: ifcopenshell.entity_instance) -> None:
if reference.InnerReference:
self.delete_reference(reference.InnerReference)
self.file.remove(reference)
@@ -32,41 +32,35 @@ def unassign_constraint(
other products.
:param products: The list of products the constraint applies to.
:type products: list[ifcopenshell.entity_instance]
:param constraint: The IfcObjective constraint
:type constraint: ifcopenshell.entity_instance
:return: None
:rtype: None
"""
usecase = Usecase()
usecase.file = file
usecase.settings = {
"products": products,
"constraint": constraint,
}
return usecase.execute()
return usecase.execute(products, constraint)
class Usecase:
def execute(self):
products = set(self.settings["products"])
if not products:
return
file: ifcopenshell.file
self.constraint = self.settings["constraint"]
rels = self.get_constraint_rels()
def execute(self, products_: list[ifcopenshell.entity_instance], constraint: ifcopenshell.entity_instance):
if not products_:
return
products_set = set(products_)
rels = self.get_constraint_rels(constraint)
related_objects = set()
for rel in rels:
related_objects.update(rel.RelatedObjects)
if not related_objects.intersection(products):
if not related_objects.intersection(products_set):
return
for rel in rels:
related_objects = set(rel.RelatedObjects)
if not related_objects.intersection(products):
if not related_objects.intersection(products_set):
continue
related_objects -= products
related_objects -= products_set
if related_objects:
rel.RelatedObjects = list(related_objects)
ifcopenshell.api.owner.update_owner_history(self.file, **{"element": rel})
@@ -77,9 +71,9 @@ class Usecase:
if history:
ifcopenshell.util.element.remove_deep2(self.file, history)
def get_constraint_rels(self) -> list[ifcopenshell.entity_instance]:
def get_constraint_rels(self, cosntraint: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
rels = []
for rel in self.file.get_inverse(self.constraint):
for rel in self.file.get_inverse(cosntraint):
if rel.is_a("IfcRelAssociatesConstraint"):
rels.append(rel)
return rels