mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 02:07:36 +00:00
New workspace tool to query chunked models
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from . import ui, prop, operator
|
from . import ui, prop, operator, workspace
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
operator.AppendEntireLibrary,
|
operator.AppendEntireLibrary,
|
||||||
@@ -54,6 +54,7 @@ classes = (
|
|||||||
operator.zxc,
|
operator.zxc,
|
||||||
operator.aaa,
|
operator.aaa,
|
||||||
operator.asdfasdf,
|
operator.asdfasdf,
|
||||||
|
operator.QueryLinkedElement,
|
||||||
prop.LibraryElement,
|
prop.LibraryElement,
|
||||||
prop.FilterCategory,
|
prop.FilterCategory,
|
||||||
prop.Link,
|
prop.Link,
|
||||||
@@ -74,6 +75,8 @@ addon_keymaps = []
|
|||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
if not bpy.app.background:
|
||||||
|
bpy.utils.register_tool(workspace.QueryTool, after={"builtin.select"}, separator=True, group=False)
|
||||||
bpy.types.Scene.BIMProjectProperties = bpy.props.PointerProperty(type=prop.BIMProjectProperties)
|
bpy.types.Scene.BIMProjectProperties = bpy.props.PointerProperty(type=prop.BIMProjectProperties)
|
||||||
bpy.types.TOPBAR_MT_file.prepend(ui.file_menu)
|
bpy.types.TOPBAR_MT_file.prepend(ui.file_menu)
|
||||||
bpy.types.TOPBAR_MT_file_context_menu.prepend(ui.file_menu)
|
bpy.types.TOPBAR_MT_file_context_menu.prepend(ui.file_menu)
|
||||||
@@ -93,6 +96,8 @@ def register():
|
|||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
|
if not bpy.app.background:
|
||||||
|
bpy.utils.unregister_tool(workspace.QueryTool)
|
||||||
bpy.types.TOPBAR_MT_file.remove(ui.file_menu)
|
bpy.types.TOPBAR_MT_file.remove(ui.file_menu)
|
||||||
bpy.types.TOPBAR_MT_file_context_menu.remove(ui.file_menu)
|
bpy.types.TOPBAR_MT_file_context_menu.remove(ui.file_menu)
|
||||||
del bpy.types.Scene.BIMProjectProperties
|
del bpy.types.Scene.BIMProjectProperties
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from blenderbim.bim.ifc import IfcStore
|
|||||||
|
|
||||||
def refresh():
|
def refresh():
|
||||||
ProjectData.is_loaded = False
|
ProjectData.is_loaded = False
|
||||||
|
LinksData.is_loaded = False
|
||||||
|
|
||||||
|
|
||||||
class ProjectData:
|
class ProjectData:
|
||||||
@@ -61,3 +62,8 @@ class ProjectData:
|
|||||||
return f"{save_date} {':'.join(save_time.split(':')[0:2])}"
|
return f"{save_date} {':'.join(save_time.split(':')[0:2])}"
|
||||||
except:
|
except:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class LinksData:
|
||||||
|
linked_data = {}
|
||||||
|
is_loaded = False
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import bpy
|
|||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import numpy as np
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
import ifcopenshell.util.selector
|
import ifcopenshell.util.selector
|
||||||
@@ -37,7 +38,8 @@ from blenderbim.bim import import_ifc
|
|||||||
from blenderbim.bim import export_ifc
|
from blenderbim.bim import export_ifc
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
import numpy as np
|
from blenderbim.bim.module.project.data import LinksData
|
||||||
|
from blenderbim.bim.module.project.decorator import ProjectDecorator
|
||||||
|
|
||||||
|
|
||||||
class NewProject(bpy.types.Operator):
|
class NewProject(bpy.types.Operator):
|
||||||
@@ -1146,13 +1148,14 @@ class xxx(bpy.types.Operator):
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from mathutils import Matrix
|
from mathutils import Matrix
|
||||||
import resource
|
import resource
|
||||||
|
|
||||||
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
collection = bpy.data.collections.new("Project")
|
collection = bpy.data.collections.new("Project")
|
||||||
# ifc_file = ifcopenshell.open('/home/dion/test.ifc')
|
# ifc_file = ifcopenshell.open('/home/dion/test.ifc')
|
||||||
# ifc_file = ifcopenshell.open('/home/dion/drive/ifcs/racbasicsampleproject.ifc')
|
# ifc_file = ifcopenshell.open('/home/dion/drive/ifcs/racbasicsampleproject.ifc')
|
||||||
ifc_file = ifcopenshell.open('/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc')
|
ifc_file = ifcopenshell.open("/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc")
|
||||||
|
|
||||||
settings = ifcopenshell.geom.settings()
|
settings = ifcopenshell.geom.settings()
|
||||||
iterator = ifcopenshell.geom.iterator(settings, ifc_file, multiprocessing.cpu_count())
|
iterator = ifcopenshell.geom.iterator(settings, ifc_file, multiprocessing.cpu_count())
|
||||||
@@ -1226,9 +1229,9 @@ class xxx(bpy.types.Operator):
|
|||||||
break
|
break
|
||||||
|
|
||||||
bpy.context.scene.collection.children.link(collection)
|
bpy.context.scene.collection.children.link(collection)
|
||||||
print('Finished', time.time() - start)
|
print("Finished", time.time() - start)
|
||||||
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
print("Mem", newmem-mem)
|
print("Mem", newmem - mem)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -1247,11 +1250,12 @@ class zzz(bpy.types.Operator):
|
|||||||
import time
|
import time
|
||||||
from mathutils import Matrix
|
from mathutils import Matrix
|
||||||
import resource
|
import resource
|
||||||
|
|
||||||
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
collection = bpy.data.collections.new("Project")
|
collection = bpy.data.collections.new("Project")
|
||||||
model = h5py.File('/home/dion/test3.h5', 'r')
|
model = h5py.File("/home/dion/test3.h5", "r")
|
||||||
# model = h5py.File('/home/dion/cpp.h5', 'r')
|
# model = h5py.File('/home/dion/cpp.h5', 'r')
|
||||||
# model = h5py.File('/home/dion/test5.h5', 'r')
|
# model = h5py.File('/home/dion/test5.h5', 'r')
|
||||||
# model = h5py.File('/home/dion/test4.h5', 'r')
|
# model = h5py.File('/home/dion/test4.h5', 'r')
|
||||||
@@ -1306,9 +1310,9 @@ class zzz(bpy.types.Operator):
|
|||||||
collection.objects.link(obj)
|
collection.objects.link(obj)
|
||||||
|
|
||||||
bpy.context.scene.collection.children.link(collection)
|
bpy.context.scene.collection.children.link(collection)
|
||||||
print('Finished', time.time() - start)
|
print("Finished", time.time() - start)
|
||||||
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
print("Mem", newmem-mem)
|
print("Mem", newmem - mem)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -1326,13 +1330,14 @@ class zxc(bpy.types.Operator):
|
|||||||
import time
|
import time
|
||||||
from mathutils import Matrix
|
from mathutils import Matrix
|
||||||
import resource
|
import resource
|
||||||
|
|
||||||
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
self.collection = bpy.data.collections.new("Project")
|
self.collection = bpy.data.collections.new("Project")
|
||||||
model = h5py.File('/home/dion/test3.h5', 'r')
|
model = h5py.File("/home/dion/test3.h5", "r")
|
||||||
# model = h5py.File('/home/dion/test5.h5', 'r')
|
# model = h5py.File('/home/dion/test5.h5', 'r')
|
||||||
print('Opened', time.time() - start)
|
print("Opened", time.time() - start)
|
||||||
|
|
||||||
materials = {}
|
materials = {}
|
||||||
for i, rgb in enumerate(model["materials"]):
|
for i, rgb in enumerate(model["materials"]):
|
||||||
@@ -1340,7 +1345,7 @@ class zxc(bpy.types.Operator):
|
|||||||
blender_mat.diffuse_color = rgb[()].tolist()
|
blender_mat.diffuse_color = rgb[()].tolist()
|
||||||
materials[i] = blender_mat
|
materials[i] = blender_mat
|
||||||
|
|
||||||
print('Materials', time.time() - start)
|
print("Materials", time.time() - start)
|
||||||
|
|
||||||
shapes = {}
|
shapes = {}
|
||||||
for shape_id, shape in model["shapes"].items():
|
for shape_id, shape in model["shapes"].items():
|
||||||
@@ -1354,7 +1359,7 @@ class zxc(bpy.types.Operator):
|
|||||||
"material_ids": shape["material_ids"][()].tolist() if "material_ids" in shape else None,
|
"material_ids": shape["material_ids"][()].tolist() if "material_ids" in shape else None,
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Shapes', time.time() - start)
|
print("Shapes", time.time() - start)
|
||||||
|
|
||||||
chunk_size = 10000
|
chunk_size = 10000
|
||||||
|
|
||||||
@@ -1410,9 +1415,9 @@ class zxc(bpy.types.Operator):
|
|||||||
self.create_object(chunked_verts, chunked_faces, chunked_materials, chunked_material_ids)
|
self.create_object(chunked_verts, chunked_faces, chunked_materials, chunked_material_ids)
|
||||||
|
|
||||||
bpy.context.scene.collection.children.link(self.collection)
|
bpy.context.scene.collection.children.link(self.collection)
|
||||||
print('Finished', time.time() - start)
|
print("Finished", time.time() - start)
|
||||||
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
print("Mem", newmem-mem)
|
print("Mem", newmem - mem)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def apply_matrix_to_flat_list(self, flat_list, matrix):
|
def apply_matrix_to_flat_list(self, flat_list, matrix):
|
||||||
@@ -1470,6 +1475,7 @@ class aaa(bpy.types.Operator):
|
|||||||
import time
|
import time
|
||||||
from mathutils import Matrix
|
from mathutils import Matrix
|
||||||
import resource
|
import resource
|
||||||
|
|
||||||
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
@@ -1491,12 +1497,14 @@ class aaa(bpy.types.Operator):
|
|||||||
# e.get_faces()
|
# e.get_faces()
|
||||||
# self.create_object(e.verts, e.faces, e.get_materials(), e.get_material_ids()) # 14.7
|
# self.create_object(e.verts, e.faces, e.get_materials(), e.get_material_ids()) # 14.7
|
||||||
# self.create_object(list(e.verts), list(e.faces), e.get_materials(), e.get_material_ids()) # 8.9
|
# self.create_object(list(e.verts), list(e.faces), e.get_materials(), e.get_material_ids()) # 8.9
|
||||||
self.create_object(e.get_verts(), e.get_faces(), e.get_materials(), e.get_material_ids()) # 6.5
|
o = self.create_object(e.get_verts(), e.get_faces(), e.get_materials(), e.get_material_ids()) # 6.5
|
||||||
|
o["guids"] = [ifcopenshell.guid.compress(g) for g in list(e.guids)]
|
||||||
|
o["guid_ids"] = list(e.guid_ids)
|
||||||
|
|
||||||
bpy.context.scene.collection.children.link(self.collection)
|
bpy.context.scene.collection.children.link(self.collection)
|
||||||
print('Finished', time.time() - start)
|
print("Finished", time.time() - start)
|
||||||
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
print("Mem", newmem-mem)
|
print("Mem", newmem - mem)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def create_object(self, verts, faces, materials, material_ids):
|
def create_object(self, verts, faces, materials, material_ids):
|
||||||
@@ -1529,6 +1537,8 @@ class aaa(bpy.types.Operator):
|
|||||||
obj = bpy.data.objects.new("Blah", mesh)
|
obj = bpy.data.objects.new("Blah", mesh)
|
||||||
self.collection.objects.link(obj)
|
self.collection.objects.link(obj)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class asdfasdf(bpy.types.Operator):
|
class asdfasdf(bpy.types.Operator):
|
||||||
bl_idname = "bim.asdfasdf"
|
bl_idname = "bim.asdfasdf"
|
||||||
@@ -1543,18 +1553,19 @@ class asdfasdf(bpy.types.Operator):
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from mathutils import Matrix
|
from mathutils import Matrix
|
||||||
import resource
|
import resource
|
||||||
|
|
||||||
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
self.collection = bpy.data.collections.new("Project")
|
self.collection = bpy.data.collections.new("Project")
|
||||||
# ifc_file = ifcopenshell.open('/home/dion/test.ifc')
|
# ifc_file = ifcopenshell.open('/home/dion/test.ifc')
|
||||||
# ifc_file = ifcopenshell.open('/home/dion/drive/ifcs/racbasicsampleproject.ifc')
|
ifc_file = ifcopenshell.open("/home/dion/drive/ifcs/racbasicsampleproject.ifc")
|
||||||
# ifc_file = ifcopenshell.open('/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc')
|
# ifc_file = ifcopenshell.open('/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc')
|
||||||
ifc_file = ifcopenshell.open("/home/dion/tmp/petrubug/F-ELECT.ifc")
|
# ifc_file = ifcopenshell.open("/home/dion/tmp/petrubug/F-ELECT.ifc")
|
||||||
print("Finished opening")
|
print("Finished opening")
|
||||||
|
|
||||||
settings = ifcopenshell.geom.settings()
|
settings = ifcopenshell.geom.settings()
|
||||||
settings.set_context_ids([ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW").id()])
|
# settings.set_context_ids([ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW").id()])
|
||||||
els = set(ifc_file.by_type("IfcElement"))
|
els = set(ifc_file.by_type("IfcElement"))
|
||||||
els |= set(ifc_file.by_type("IfcSite"))
|
els |= set(ifc_file.by_type("IfcSite"))
|
||||||
els -= set(ifc_file.by_type("IfcFeatureElement"))
|
els -= set(ifc_file.by_type("IfcFeatureElement"))
|
||||||
@@ -1569,7 +1580,9 @@ class asdfasdf(bpy.types.Operator):
|
|||||||
ci = 0
|
ci = 0
|
||||||
if iterator.initialize():
|
if iterator.initialize():
|
||||||
while True:
|
while True:
|
||||||
|
has_processed_chunk = False
|
||||||
if iterator.process_chunk():
|
if iterator.process_chunk():
|
||||||
|
has_processed_chunk = True
|
||||||
ci += 1
|
ci += 1
|
||||||
print("Doing chunk", ci)
|
print("Doing chunk", ci)
|
||||||
e = iterator.get_chunk()
|
e = iterator.get_chunk()
|
||||||
@@ -1579,18 +1592,34 @@ class asdfasdf(bpy.types.Operator):
|
|||||||
blender_mat.diffuse_color = list(c)
|
blender_mat.diffuse_color = list(c)
|
||||||
self.materials.append(blender_mat)
|
self.materials.append(blender_mat)
|
||||||
total_materials += 1
|
total_materials += 1
|
||||||
self.create_object(e.get_verts(), e.get_faces(), e.get_materials(), e.get_material_ids())
|
o = self.create_object(e.get_verts(), e.get_faces(), e.get_materials(), e.get_material_ids())
|
||||||
|
o["guids"] = list(e.guids)
|
||||||
|
o["guid_ids"] = list(e.guid_ids)
|
||||||
if not iterator.next():
|
if not iterator.next():
|
||||||
|
if not has_processed_chunk:
|
||||||
|
# The left over chunk
|
||||||
|
e = iterator.get_chunk()
|
||||||
|
for c in e.colours:
|
||||||
|
blender_mat = bpy.data.materials.new(str(total_materials))
|
||||||
|
blender_mat.diffuse_color = list(c)
|
||||||
|
self.materials.append(blender_mat)
|
||||||
|
total_materials += 1
|
||||||
|
|
||||||
|
o = self.create_object(e.get_verts(), e.get_faces(), e.get_materials(), e.get_material_ids())
|
||||||
|
o["guids"] = list(e.guids)
|
||||||
|
o["guid_ids"] = list(e.guid_ids)
|
||||||
break
|
break
|
||||||
|
|
||||||
bpy.context.scene.collection.children.link(self.collection)
|
bpy.context.scene.collection.children.link(self.collection)
|
||||||
print('Finished', time.time() - start)
|
print("Finished", time.time() - start)
|
||||||
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000
|
||||||
print("Mem", newmem-mem)
|
print("Mem", newmem - mem)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def create_object(self, verts, faces, materials, material_ids):
|
def create_object(self, verts, faces, materials, material_ids):
|
||||||
num_vertices = len(verts) // 3
|
num_vertices = len(verts) // 3
|
||||||
|
if not num_vertices:
|
||||||
|
return
|
||||||
total_faces = len(faces)
|
total_faces = len(faces)
|
||||||
loop_start = range(0, total_faces, 3)
|
loop_start = range(0, total_faces, 3)
|
||||||
num_loops = total_faces // 3
|
num_loops = total_faces // 3
|
||||||
@@ -1618,3 +1647,105 @@ class asdfasdf(bpy.types.Operator):
|
|||||||
|
|
||||||
obj = bpy.data.objects.new("Blah", mesh)
|
obj = bpy.data.objects.new("Blah", mesh)
|
||||||
self.collection.objects.link(obj)
|
self.collection.objects.link(obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
class QueryLinkedElement(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.query_linked_element"
|
||||||
|
bl_label = "Query Linked Element"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context.area.type == "VIEW_3D"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_origin_3d
|
||||||
|
|
||||||
|
bpy.context.scene.BIMProjectProperties.queried_obj = None
|
||||||
|
|
||||||
|
region = context.region
|
||||||
|
rv3d = context.region_data
|
||||||
|
coord = (self.mouse_x, self.mouse_y)
|
||||||
|
origin = region_2d_to_origin_3d(region, rv3d, coord)
|
||||||
|
direction = region_2d_to_vector_3d(region, rv3d, coord)
|
||||||
|
hit, location, normal, face_index, obj, matrix = self.ray_cast(context, origin, direction)
|
||||||
|
if not hit:
|
||||||
|
self.report({"INFO"}, "No object found.")
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
if "guids" not in obj:
|
||||||
|
self.report({"INFO"}, "Object is not a linked IFC element.")
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
guid = None
|
||||||
|
guid_start_index = 0
|
||||||
|
for i, guid_end_index in enumerate(obj["guid_ids"]):
|
||||||
|
if face_index < guid_end_index:
|
||||||
|
guid = obj["guids"][i]
|
||||||
|
bpy.context.scene.BIMProjectProperties.queried_obj = obj
|
||||||
|
|
||||||
|
selected_tris = []
|
||||||
|
selected_edges = []
|
||||||
|
vert_indices = set()
|
||||||
|
for polygon in obj.data.polygons[guid_start_index:guid_end_index]:
|
||||||
|
vert_indices.update(polygon.vertices)
|
||||||
|
vert_indices = list(vert_indices)
|
||||||
|
vert_map = {k: v for v, k in enumerate(vert_indices)}
|
||||||
|
selected_vertices = [tuple(obj.data.vertices[vi].co) for vi in vert_indices]
|
||||||
|
for polygon in obj.data.polygons[guid_start_index:guid_end_index]:
|
||||||
|
selected_tris.append(tuple(vert_map[v] for v in polygon.vertices))
|
||||||
|
selected_edges.extend(tuple([vert_map[vi] for vi in e] for e in polygon.edge_keys))
|
||||||
|
|
||||||
|
obj["selected_vertices"] = selected_vertices
|
||||||
|
obj["selected_edges"] = selected_edges
|
||||||
|
obj["selected_tris"] = selected_tris
|
||||||
|
|
||||||
|
break
|
||||||
|
guid_start_index = guid_end_index
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
self.db = sqlite3.connect("/home/dion/Projects/ifcopenshell/src/ifcclash/foo.sqlite")
|
||||||
|
self.c = self.db.cursor()
|
||||||
|
|
||||||
|
self.c.execute(f"SELECT * FROM elements WHERE global_id = '{guid}' LIMIT 1")
|
||||||
|
element = self.c.fetchone()
|
||||||
|
|
||||||
|
attributes = {}
|
||||||
|
for i, attr in enumerate(["GlobalId", "IFC Class", "Predefined Type", "Name", "Description"]):
|
||||||
|
if element[i + 1] is not None:
|
||||||
|
attributes[attr] = element[i + 1]
|
||||||
|
|
||||||
|
self.c.execute("SELECT * FROM properties WHERE element_id = ?", (element[0],))
|
||||||
|
rows = self.c.fetchall()
|
||||||
|
|
||||||
|
properties = {}
|
||||||
|
for row in rows:
|
||||||
|
properties.setdefault(row[1], {})[row[2]] = row[3]
|
||||||
|
|
||||||
|
sorted_properties = [(k, properties[k]) for k in sorted(properties.keys())]
|
||||||
|
|
||||||
|
LinksData.linked_data = {"attributes": attributes, "properties": sorted_properties}
|
||||||
|
|
||||||
|
for area in bpy.context.screen.areas:
|
||||||
|
if area.type == "PROPERTIES":
|
||||||
|
for region in area.regions:
|
||||||
|
if region.type == "WINDOW":
|
||||||
|
region.tag_redraw()
|
||||||
|
elif area.type == "VIEW_3D":
|
||||||
|
area.tag_redraw()
|
||||||
|
|
||||||
|
self.report({"INFO"}, f"Loaded data for {guid}")
|
||||||
|
ProjectDecorator.install(bpy.context)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def ray_cast(self, context, origin, direction):
|
||||||
|
depsgraph = context.evaluated_depsgraph_get()
|
||||||
|
result = context.scene.ray_cast(depsgraph, origin, direction)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
self.mouse_x = event.mouse_region_x
|
||||||
|
self.mouse_y = event.mouse_region_y
|
||||||
|
return self.execute(context)
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ class BIMProjectProperties(PropertyGroup):
|
|||||||
export_schema: EnumProperty(items=get_export_schema, name="IFC Schema")
|
export_schema: EnumProperty(items=get_export_schema, name="IFC Schema")
|
||||||
template_file: EnumProperty(items=get_template_file, name="Template File")
|
template_file: EnumProperty(items=get_template_file, name="Template File")
|
||||||
use_relative_project_path: BoolProperty(name="Use Relative Project Path", default=False)
|
use_relative_project_path: BoolProperty(name="Use Relative Project Path", default=False)
|
||||||
|
queried_obj: bpy.props.PointerProperty(type=bpy.types.Object)
|
||||||
|
|
||||||
def get_library_element_index(self, lib_element):
|
def get_library_element_index(self, lib_element):
|
||||||
return next((i for i in range(len(self.library_elements)) if self.library_elements[i] == lib_element))
|
return next((i for i in range(len(self.library_elements)) if self.library_elements[i] == lib_element))
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import blenderbim.bim
|
|||||||
from blenderbim.bim.helper import prop_with_search
|
from blenderbim.bim.helper import prop_with_search
|
||||||
from bpy.types import Panel, Menu, UIList
|
from bpy.types import Panel, Menu, UIList
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.module.project.data import ProjectData
|
from blenderbim.bim.module.project.data import ProjectData, LinksData
|
||||||
|
|
||||||
|
|
||||||
class BIM_MT_project(Menu):
|
class BIM_MT_project(Menu):
|
||||||
@@ -307,6 +307,23 @@ class BIM_PT_links(Panel):
|
|||||||
"active_link_index",
|
"active_link_index",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not LinksData.linked_data:
|
||||||
|
return
|
||||||
|
|
||||||
|
for name, value in LinksData.linked_data["attributes"].items():
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.label(text=name)
|
||||||
|
row.label(text=value)
|
||||||
|
|
||||||
|
for pset in LinksData.linked_data["properties"]:
|
||||||
|
box = self.layout.box()
|
||||||
|
row = box.row(align=True)
|
||||||
|
row.label(text=pset[0], icon="COPY_ID")
|
||||||
|
for name, value in pset[1].items():
|
||||||
|
row = box.row(align=True)
|
||||||
|
row.label(text=name)
|
||||||
|
row.label(text=value)
|
||||||
|
|
||||||
|
|
||||||
class BIM_UL_library(UIList):
|
class BIM_UL_library(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
|
|||||||
Reference in New Issue
Block a user