mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
Merge pull request #3364 from IfcOpenShell/interface-to-interact-with-Brickschema
Interface to interact with brickschema PR #1
This commit is contained in:
+4
-1
@@ -94,4 +94,7 @@ src/ifcopenshell-python/ifcopenshell/_ifcopenshell_wrapper.so
|
||||
src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.py
|
||||
|
||||
# apple
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
|
||||
# Brickschema
|
||||
src/blenderbim/blenderbim/bim/schema/Brick.ttl
|
||||
@@ -33,6 +33,9 @@ classes = (
|
||||
operator.RewindBrickClass,
|
||||
operator.ViewBrickClass,
|
||||
operator.ViewBrickItem,
|
||||
operator.UndoBrick,
|
||||
operator.RedoBrick,
|
||||
operator.SerializeBrick,
|
||||
prop.Brick,
|
||||
prop.BIMBrickProperties,
|
||||
ui.BIM_PT_brickschema,
|
||||
|
||||
@@ -110,7 +110,8 @@ class BrickschemaData:
|
||||
return []
|
||||
results = []
|
||||
for alias, uri in BrickStore.graph.namespaces():
|
||||
results.append((uri, f"{alias}: {uri}", ""))
|
||||
# results.append((uri, f"{alias}: {uri}", ""))
|
||||
results.append((uri, f"{alias}", ""))
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -189,3 +189,24 @@ class RemoveBrick(bpy.types.Operator, Operator):
|
||||
library=tool.Ifc.get().by_id(int(props.libraries)) if props.libraries else None,
|
||||
brick_uri=props.bricks[props.active_brick_index].uri,
|
||||
)
|
||||
|
||||
class UndoBrick(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.undo_brick"
|
||||
bl_label = "Undo Brick"
|
||||
|
||||
def _execute(self, context):
|
||||
core.undo_brick(tool.Brick)
|
||||
|
||||
class RedoBrick(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.redo_brick"
|
||||
bl_label = "Redo Brick"
|
||||
|
||||
def _execute(self, context):
|
||||
core.redo_brick(tool.Brick)
|
||||
|
||||
class SerializeBrick(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.serialize_brick"
|
||||
bl_label = "Serialize Brick"
|
||||
|
||||
def _execute(self, context):
|
||||
core.serialize_brick(tool.Brick)
|
||||
@@ -58,6 +58,13 @@ class BIM_PT_brickschema(Panel):
|
||||
row.operator("bim.add_brick_feed", text="", icon="PLUGIN")
|
||||
row.operator("bim.remove_brick", text="", icon="X")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.undo_brick", icon="LOOP_BACK")
|
||||
row.operator("bim.redo_brick", icon="LOOP_FORWARDS")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.serialize_brick")
|
||||
|
||||
self.layout.template_list("BIM_UL_bricks", "", self.props, "bricks", self.props, "active_brick_index")
|
||||
|
||||
for attribute in BrickschemaData.data["attributes"]:
|
||||
|
||||
@@ -109,3 +109,14 @@ def remove_brick(ifc, brick, library=None, brick_uri=None):
|
||||
ifc.run("library.remove_reference", reference=reference)
|
||||
brick.remove_brick(brick_uri)
|
||||
brick.run_refresh_brick_viewer()
|
||||
|
||||
def undo_brick(brick):
|
||||
brick.undo_brick()
|
||||
brick.run_refresh_brick_viewer()
|
||||
|
||||
def redo_brick(brick):
|
||||
brick.redo_brick()
|
||||
brick.run_refresh_brick_viewer()
|
||||
|
||||
def serialize_brick(brick, file_name="BlenderBIMSerializeTest.ttl"):
|
||||
brick.serialize_brick(file_name)
|
||||
@@ -25,6 +25,7 @@ import blenderbim.tool as tool
|
||||
|
||||
try:
|
||||
import brickschema
|
||||
import brickschema.persistent
|
||||
import urllib.parse
|
||||
from rdflib import Literal, URIRef, Namespace
|
||||
from rdflib.namespace import RDF
|
||||
@@ -32,14 +33,20 @@ except:
|
||||
# See #1860
|
||||
print("Warning: brickschema not available.")
|
||||
|
||||
# silence known rdflib_sqlalchemy TypeError warning
|
||||
# see https://github.com/BrickSchema/Brick/issues/513#issuecomment-1558493675
|
||||
import logging
|
||||
logger = logging.getLogger("rdflib")
|
||||
logger.setLevel(logging.ERROR)
|
||||
|
||||
class Brick(blenderbim.core.tool.Brick):
|
||||
@classmethod
|
||||
def add_brick(cls, namespace, brick_class):
|
||||
ns = Namespace(namespace)
|
||||
brick = ns[ifcopenshell.guid.expand(ifcopenshell.guid.new())]
|
||||
BrickStore.graph.add((brick, RDF.type, URIRef(brick_class)))
|
||||
BrickStore.graph.add((brick, URIRef("http://www.w3.org/2000/01/rdf-schema#label"), Literal("Unnamed")))
|
||||
with BrickStore.graph.new_changeset("PROJECT") as cs:
|
||||
cs.add((brick, RDF.type, URIRef(brick_class)))
|
||||
cs.add((brick, URIRef("http://www.w3.org/2000/01/rdf-schema#label"), Literal("Unnamed")))
|
||||
return str(brick)
|
||||
|
||||
@classmethod
|
||||
@@ -100,7 +107,7 @@ class Brick(blenderbim.core.tool.Brick):
|
||||
|
||||
@classmethod
|
||||
def clear_project(cls):
|
||||
BrickStore.graph = None
|
||||
BrickStore.purge()
|
||||
bpy.context.scene.BIMBrickProperties.active_brick_class == ""
|
||||
bpy.context.scene.BIMBrickProperties.brick_breadcrumbs.clear()
|
||||
|
||||
@@ -249,24 +256,24 @@ class Brick(blenderbim.core.tool.Brick):
|
||||
|
||||
@classmethod
|
||||
def load_brick_file(cls, filepath):
|
||||
if not BrickStore.schema:
|
||||
BrickStore.schema = brickschema.Graph()
|
||||
if not BrickStore.schema: # important check for running under test cases
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
schema_path = os.path.join(cwd, "..", "bim", "schema", "Brick.ttl")
|
||||
BrickStore.schema.load_file(schema_path)
|
||||
BrickStore.graph = brickschema.Graph().load_file(filepath) + BrickStore.schema
|
||||
BrickStore.schema = os.path.join(cwd, "..", "bim", "schema", "Brick.ttl")
|
||||
BrickStore.graph = brickschema.persistent.VersionedGraphCollection("sqlite://")
|
||||
with BrickStore.graph.new_changeset("SCHEMA") as cs:
|
||||
cs.load_file(BrickStore.schema)
|
||||
with BrickStore.graph.new_changeset("PROJECT") as cs:
|
||||
cs.load_file(filepath)
|
||||
BrickStore.path = filepath
|
||||
|
||||
@classmethod
|
||||
def new_brick_file(cls):
|
||||
if not BrickStore.schema:
|
||||
BrickStore.schema = brickschema.Graph()
|
||||
#BrickStore.schema = brickschema.persistent.VersionedGraphCollection("sqlite://")
|
||||
if not BrickStore.schema: # important check for running under test cases
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
schema_path = os.path.join(cwd, "..", "bim", "schema", "Brick.ttl")
|
||||
BrickStore.schema.load_file(schema_path)
|
||||
#BrickStore.schema.load_graph(schema_path)
|
||||
BrickStore.graph = brickschema.Graph() + BrickStore.schema
|
||||
BrickStore.schema = os.path.join(cwd, "..", "bim", "schema", "Brick.ttl")
|
||||
BrickStore.graph = brickschema.persistent.VersionedGraphCollection("sqlite://")
|
||||
with BrickStore.graph.new_changeset("SCHEMA") as cs:
|
||||
cs.load_file(BrickStore.schema)
|
||||
BrickStore.graph.bind("digitaltwin", Namespace("https://example.org/digitaltwin#"))
|
||||
BrickStore.graph.bind("brick", Namespace("https://brickschema.org/schema/Brick#"))
|
||||
BrickStore.graph.bind("rdfs", Namespace("http://www.w3.org/2000/01/rdf-schema#"))
|
||||
@@ -281,8 +288,10 @@ class Brick(blenderbim.core.tool.Brick):
|
||||
|
||||
@classmethod
|
||||
def remove_brick(cls, brick_uri):
|
||||
for triple in BrickStore.graph.triples((URIRef(brick_uri), None, None)):
|
||||
BrickStore.graph.remove(triple)
|
||||
if(BrickStore.graph.triples((URIRef(brick_uri), None, None))):
|
||||
with BrickStore.graph.new_changeset("PROJECT") as cs:
|
||||
for triple in BrickStore.graph.triples((URIRef(brick_uri), None, None)):
|
||||
cs.remove(triple)
|
||||
|
||||
@classmethod
|
||||
def run_assign_brick_reference(cls, element=None, library=None, brick_uri=None):
|
||||
@@ -308,14 +317,39 @@ class Brick(blenderbim.core.tool.Brick):
|
||||
def set_active_brick_class(cls, brick_class):
|
||||
bpy.context.scene.BIMBrickProperties.active_brick_class = brick_class
|
||||
|
||||
@classmethod
|
||||
def undo_brick(cls):
|
||||
if(len(BrickStore.graph.versions()) > 1):
|
||||
BrickStore.graph.undo()
|
||||
|
||||
@classmethod
|
||||
def redo_brick(cls):
|
||||
with BrickStore.graph.conn() as conn:
|
||||
redo_record = conn.execute(
|
||||
"SELECT * from redos " "ORDER BY timestamp ASC LIMIT 1"
|
||||
).fetchone()
|
||||
if redo_record is not None:
|
||||
BrickStore.graph.redo()
|
||||
|
||||
@classmethod
|
||||
def serialize_brick(cls, file_name):
|
||||
#temporary file path, could either be user selected for "save as" or use the BrickStore.path for simply "save"
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
dest = os.path.join(cwd, "..", "bim", "schema", file_name)
|
||||
BrickStore.get_project().serialize(destination=dest, format="turtle")
|
||||
|
||||
class BrickStore:
|
||||
schema = None
|
||||
graph = None
|
||||
path = None
|
||||
|
||||
schema = None # this is now a os path
|
||||
path = None # file path if the project was loaded in
|
||||
graph = None # this is the VersionedGraphCollection with 2 arbitrarily named graphs: "schema" and "project"
|
||||
# "SCHEMA" holds the Brick.ttl metadata; "PROJECT" holds all the authored entities
|
||||
|
||||
@staticmethod
|
||||
def purge():
|
||||
BrickStore.schema = None
|
||||
BrickStore.graph = None
|
||||
BrickStore.path = None
|
||||
BrickStore.path = None
|
||||
|
||||
@classmethod
|
||||
def get_project(cls):
|
||||
return BrickStore.graph.graph_at(graph="PROJECT")
|
||||
@@ -307,10 +307,8 @@ class TestImportBrickItems(NewFile):
|
||||
class TestLoadBrickFile(NewFile):
|
||||
def test_run(self):
|
||||
# We stub the schema to make tests run faster
|
||||
BrickStore.schema = brickschema.Graph()
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
schema_path = os.path.join(cwd, "..", "files", "BrickStub.ttl")
|
||||
BrickStore.schema.load_file(schema_path)
|
||||
BrickStore.schema = os.path.join(cwd, "..", "files", "BrickStub.ttl")
|
||||
|
||||
# This is the actual test
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
@@ -322,10 +320,8 @@ class TestLoadBrickFile(NewFile):
|
||||
class TestNewBrickFile(NewFile):
|
||||
def test_run(self):
|
||||
# We stub the schema to make tests run faster
|
||||
BrickStore.schema = brickschema.Graph()
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
schema_path = os.path.join(cwd, "..", "files", "BrickStub.ttl")
|
||||
BrickStore.schema.load_file(schema_path)
|
||||
BrickStore.schema = os.path.join(cwd, "..", "files", "BrickStub.ttl")
|
||||
|
||||
# This is the actual test
|
||||
subject.new_brick_file()
|
||||
|
||||
Reference in New Issue
Block a user