From c022a12835b378e2d92ea79b8bd22bf4c6b70b0b Mon Sep 17 00:00:00 2001 From: rileywong311 Date: Thu, 17 Aug 2023 15:55:54 -0700 Subject: [PATCH] Support displaying Brick Bnode relations - Important for Ifc External References and other data. - Set predicate_uri of predicates of the Bnode to None, which is used to remove the ability to delete the relationship in the UI. - Also added try/excepts to difficult edge cases such as the object_uri not having a "#" character in it (such as "") and the object_uri not being a brick class, which breaks "view_brick_item". - Removing a Bnode type from the entity's relation removes all relations of the Bnode also --- .../blenderbim/bim/module/brick/data.py | 55 ++++++++++++------- .../blenderbim/bim/module/brick/operator.py | 5 +- .../blenderbim/bim/module/brick/ui.py | 6 +- src/blenderbim/blenderbim/tool/brick.py | 14 +++-- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/brick/data.py b/src/blenderbim/blenderbim/bim/module/brick/data.py index c52800111a..b08e25280c 100644 --- a/src/blenderbim/blenderbim/bim/module/brick/data.py +++ b/src/blenderbim/blenderbim/bim/module/brick/data.py @@ -75,37 +75,52 @@ class BrickschemaData: { ?predicate a brick:EntityProperty . } ?object ?sp ?sv } } + GROUP BY ?object """.replace( "{uri}", uri ) ) for row in query: - predicate = row.get("predicate") - predicate_name = predicate.toPython().split("#")[-1] - object = row.get("object") - object_name = object.toPython().split("#")[-1] + predicate_uri = row.get("predicate") + predicate_name = predicate_uri.toPython().split("#")[-1] + object_uri = row.get("object") + print("DEBUG: object is ", object_uri) + if isinstance(object_uri, BNode): + object_name = "[]" + else: + try: + object_name = object_uri.toPython().split("#")[-1] + except: + object_name = str(object_uri) results.append( { - "predicate": predicate, + "predicate_uri": predicate_uri, "predicate_name": predicate_name, - "object": object, + "object_uri": object_uri, "object_name": object_name, - "is_uri": isinstance(object, URIRef), - "object_uri": object.toPython(), - "is_globalid": predicate == "globalID", + "is_uri": isinstance(object_uri, URIRef), + "is_globalid": predicate_uri == "globalID", } ) - # if isinstance(row.get("object"), BNode): - # for s, p, o in BrickStore.graph.triples((object, None, None)): - # results.append( - # { - # "predicate": predicate + ":" + p.toPython().split("#")[-1], - # "object": o.toPython().split("#")[-1], - # "is_uri": isinstance(o, URIRef), - # "object_uri": o.toPython(), - # "is_globalid": p.toPython().split("#")[-1] == "globalID", - # } - # ) + if isinstance(object_uri, BNode): + for subject2, predicate2, object2 in BrickStore.graph.triples((object_uri, None, None)): + predicate2_name = predicate2.toPython().split("#")[-1] + try: + object2_name = object2.toPython().split("#")[-1] + except: + object2_name = str(object2) + print("DEBUG: ", predicate_name, ":", predicate2_name) + results.append( + { + "predicate_uri": None, + "predicate_name": predicate_name + ":" + predicate2_name, + "object_uri": object2, + "object_name": object2_name, + "is_uri": isinstance(object2, URIRef), + "is_globalid": predicate2_name == "globalID", + } + ) + print("") return results diff --git a/src/blenderbim/blenderbim/bim/module/brick/operator.py b/src/blenderbim/blenderbim/bim/module/brick/operator.py index 4bd2015b71..88a25b90b4 100644 --- a/src/blenderbim/blenderbim/bim/module/brick/operator.py +++ b/src/blenderbim/blenderbim/bim/module/brick/operator.py @@ -74,7 +74,10 @@ class ViewBrickItem(bpy.types.Operator, Operator): split_screen: bpy.props.BoolProperty(name="Split Screen", default=False, options={"HIDDEN"}) def _execute(self, context): - core.view_brick_item(tool.Brick, item=self.item, split_screen=self.split_screen) + try: + core.view_brick_item(tool.Brick, item=self.item, split_screen=self.split_screen) + except: + self.report({'ERROR'}, f'Could not find {self.item}') class RewindBrickClass(bpy.types.Operator, Operator): diff --git a/src/blenderbim/blenderbim/bim/module/brick/ui.py b/src/blenderbim/blenderbim/bim/module/brick/ui.py index 039afbabb4..a9b19d526d 100644 --- a/src/blenderbim/blenderbim/bim/module/brick/ui.py +++ b/src/blenderbim/blenderbim/bim/module/brick/ui.py @@ -184,10 +184,10 @@ class BIM_PT_brickschema(Panel): row = self.layout.row(align=True) row.label(text=relation["predicate_name"]) row.label(text=relation["object_name"]) - if self.props.brick_edit_relations_toggled and relation["predicate_name"] != "type": + if self.props.brick_edit_relations_toggled and relation["predicate_uri"] and relation["predicate_name"] != "type": op = row.operator("bim.remove_brick_relation", text="", icon="UNLINKED") - op.predicate = relation["predicate"] - op.object = relation["object"] + op.predicate = relation["predicate_uri"] + op.object = relation["object_uri"] if relation["is_uri"] and relation["object_name"] != self.props.active_brick_class: op = row.operator("bim.view_brick_item", text="", icon="DISCLOSURE_TRI_RIGHT") op.item = relation["object_uri"] diff --git a/src/blenderbim/blenderbim/tool/brick.py b/src/blenderbim/blenderbim/tool/brick.py index 2da3ebf9ed..91f732dafc 100644 --- a/src/blenderbim/blenderbim/tool/brick.py +++ b/src/blenderbim/blenderbim/tool/brick.py @@ -123,8 +123,11 @@ class Brick(blenderbim.core.tool.Brick): @classmethod def remove_relation(cls, brick_uri, predicate, object): with BrickStore.new_changeset() as cs: - for triple in BrickStore.graph.triples((brick_uri, predicate, object)): - cs.remove(triple) + for s, p, o in BrickStore.graph.triples((brick_uri, predicate, object)): + cs.remove((s, p, o)) + if isinstance(o, BNode): + for triple in BrickStore.graph.triples((object, None, None)): + cs.remove(triple) @classmethod def clear_brick_browser(cls, split_screen=False): @@ -340,8 +343,11 @@ class Brick(blenderbim.core.tool.Brick): @classmethod def remove_brick(cls, brick_uri): with BrickStore.new_changeset() as cs: - for triple in BrickStore.graph.triples((URIRef(brick_uri), None, None)): - cs.remove(triple) + for s, p, o in BrickStore.graph.triples((URIRef(brick_uri), None, None)): + cs.remove((s, p, o)) + if isinstance(o, BNode): + for triple in BrickStore.graph.triples((o, None, None)): + cs.remove(triple) @classmethod def run_assign_brick_reference(cls, element=None, library=None, brick_uri=None):