mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Drawings now load on-demand instead of at project load. See #2520.
This commit is contained in:
@@ -236,8 +236,6 @@ class IfcImporter:
|
|||||||
self.profile_code("Create materials")
|
self.profile_code("Create materials")
|
||||||
self.create_styles()
|
self.create_styles()
|
||||||
self.profile_code("Create styles")
|
self.profile_code("Create styles")
|
||||||
self.create_annotations()
|
|
||||||
self.profile_code("Create annotation")
|
|
||||||
self.parse_native_elements()
|
self.parse_native_elements()
|
||||||
self.profile_code("Parsing native elements")
|
self.profile_code("Parsing native elements")
|
||||||
self.create_native_elements()
|
self.create_native_elements()
|
||||||
@@ -586,7 +584,7 @@ class IfcImporter:
|
|||||||
if bpy.context.preferences.addons["blenderbim"].preferences.lock_grids_on_import:
|
if bpy.context.preferences.addons["blenderbim"].preferences.lock_grids_on_import:
|
||||||
grid_obj.lock_location = (True, True, True)
|
grid_obj.lock_location = (True, True, True)
|
||||||
grid_obj.lock_rotation = (True, True, True)
|
grid_obj.lock_rotation = (True, True, True)
|
||||||
collection = bpy.data.collections.new(self.get_name(grid))
|
collection = bpy.data.collections.new(tool.Loader.get_name(grid))
|
||||||
u_axes = bpy.data.collections.new("UAxes")
|
u_axes = bpy.data.collections.new("UAxes")
|
||||||
collection.children.link(u_axes)
|
collection.children.link(u_axes)
|
||||||
v_axes = bpy.data.collections.new("VAxes")
|
v_axes = bpy.data.collections.new("VAxes")
|
||||||
@@ -628,11 +626,11 @@ class IfcImporter:
|
|||||||
try:
|
try:
|
||||||
shape = ifcopenshell.geom.create_shape(self.settings, representation_map.MappedRepresentation)
|
shape = ifcopenshell.geom.create_shape(self.settings, representation_map.MappedRepresentation)
|
||||||
mesh = self.create_mesh(element, shape)
|
mesh = self.create_mesh(element, shape)
|
||||||
self.link_mesh(shape, mesh)
|
tool.Loader.link_mesh(shape, mesh)
|
||||||
self.meshes[mesh_name] = mesh
|
self.meshes[mesh_name] = mesh
|
||||||
except:
|
except:
|
||||||
self.ifc_import_settings.logger.error("Failed to generate shape for %s", element)
|
self.ifc_import_settings.logger.error("Failed to generate shape for %s", element)
|
||||||
obj = bpy.data.objects.new(self.get_name(element), mesh)
|
obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh)
|
||||||
self.link_element(element, obj)
|
self.link_element(element, obj)
|
||||||
self.material_creator.create(element, obj, mesh)
|
self.material_creator.create(element, obj, mesh)
|
||||||
self.type_products[element.GlobalId] = obj
|
self.type_products[element.GlobalId] = obj
|
||||||
@@ -687,9 +685,6 @@ class IfcImporter:
|
|||||||
def create_spatial_elements(self):
|
def create_spatial_elements(self):
|
||||||
self.create_generic_elements(self.spatial_elements)
|
self.create_generic_elements(self.spatial_elements)
|
||||||
|
|
||||||
def create_annotations(self):
|
|
||||||
self.create_generic_elements(self.annotations)
|
|
||||||
|
|
||||||
def create_elements(self):
|
def create_elements(self):
|
||||||
self.create_generic_elements(self.elements)
|
self.create_generic_elements(self.elements)
|
||||||
|
|
||||||
@@ -923,21 +918,21 @@ class IfcImporter:
|
|||||||
pass
|
pass
|
||||||
elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
|
elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
|
||||||
mesh = self.create_camera(element, shape)
|
mesh = self.create_camera(element, shape)
|
||||||
self.link_mesh(shape, mesh)
|
tool.Loader.link_mesh(shape, mesh)
|
||||||
elif element.is_a("IfcAnnotation") and self.is_curve_annotation(element) and shape:
|
elif element.is_a("IfcAnnotation") and self.is_curve_annotation(element) and shape:
|
||||||
mesh = self.create_curve(element, shape)
|
mesh = self.create_curve(element, shape)
|
||||||
self.link_mesh(shape, mesh)
|
tool.Loader.link_mesh(shape, mesh)
|
||||||
elif shape:
|
elif shape:
|
||||||
mesh_name = self.get_mesh_name(shape.geometry)
|
mesh_name = tool.Loader.get_mesh_name(shape.geometry)
|
||||||
mesh = self.meshes.get(mesh_name)
|
mesh = self.meshes.get(mesh_name)
|
||||||
if mesh is None:
|
if mesh is None:
|
||||||
mesh = self.create_mesh(element, shape)
|
mesh = self.create_mesh(element, shape)
|
||||||
self.link_mesh(shape, mesh)
|
tool.Loader.link_mesh(shape, mesh)
|
||||||
self.meshes[mesh_name] = mesh
|
self.meshes[mesh_name] = mesh
|
||||||
else:
|
else:
|
||||||
mesh = None
|
mesh = None
|
||||||
|
|
||||||
obj = bpy.data.objects.new(self.get_name(element), mesh)
|
obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh)
|
||||||
self.link_element(element, obj)
|
self.link_element(element, obj)
|
||||||
|
|
||||||
if shape:
|
if shape:
|
||||||
@@ -1385,12 +1380,6 @@ class IfcImporter:
|
|||||||
if not view_collection:
|
if not view_collection:
|
||||||
view_collection = bpy.data.collections.new("Views")
|
view_collection = bpy.data.collections.new("Views")
|
||||||
self.project["blender"].children.link(view_collection)
|
self.project["blender"].children.link(view_collection)
|
||||||
for element in self.file.by_type("IfcAnnotation"):
|
|
||||||
if element.ObjectType == "DRAWING":
|
|
||||||
group = [r for r in element.HasAssignments if r.is_a("IfcRelAssignsToGroup")][0].RelatingGroup
|
|
||||||
collection = bpy.data.collections.new("IfcGroup/" + group.Name)
|
|
||||||
self.collections[group.GlobalId] = collection
|
|
||||||
view_collection.children.link(collection)
|
|
||||||
|
|
||||||
def create_spatial_decomposition_collection(self, parent, related_objects):
|
def create_spatial_decomposition_collection(self, parent, related_objects):
|
||||||
for element in related_objects:
|
for element in related_objects:
|
||||||
@@ -1404,7 +1393,7 @@ class IfcImporter:
|
|||||||
collection = obj.users_collection[0]
|
collection = obj.users_collection[0]
|
||||||
self.collections[element.GlobalId] = collection
|
self.collections[element.GlobalId] = collection
|
||||||
if not is_existing:
|
if not is_existing:
|
||||||
collection = bpy.data.collections.new(self.get_name(element))
|
collection = bpy.data.collections.new(tool.Loader.get_name(element))
|
||||||
self.collections[element.GlobalId] = collection
|
self.collections[element.GlobalId] = collection
|
||||||
parent.children.link(collection)
|
parent.children.link(collection)
|
||||||
if element.IsDecomposedBy:
|
if element.IsDecomposedBy:
|
||||||
@@ -1432,7 +1421,7 @@ class IfcImporter:
|
|||||||
aggregates = {}
|
aggregates = {}
|
||||||
for rel_aggregate in rel_aggregates:
|
for rel_aggregate in rel_aggregates:
|
||||||
element = rel_aggregate.RelatingObject
|
element = rel_aggregate.RelatingObject
|
||||||
collection = bpy.data.collections.new(self.get_name(element))
|
collection = bpy.data.collections.new(tool.Loader.get_name(element))
|
||||||
aggregates[element.GlobalId] = {"element": element, "collection": collection}
|
aggregates[element.GlobalId] = {"element": element, "collection": collection}
|
||||||
self.collections[element.GlobalId] = collection
|
self.collections[element.GlobalId] = collection
|
||||||
|
|
||||||
@@ -1663,9 +1652,6 @@ class IfcImporter:
|
|||||||
else:
|
else:
|
||||||
blender_material.node_tree.links.new(coord.outputs["UV"], node.inputs["Vector"])
|
blender_material.node_tree.links.new(coord.outputs["UV"], node.inputs["Vector"])
|
||||||
|
|
||||||
def get_name(self, element):
|
|
||||||
return "{}/{}".format(element.is_a(), element.Name)
|
|
||||||
|
|
||||||
def place_objects_in_collections(self):
|
def place_objects_in_collections(self):
|
||||||
for ifc_definition_id, obj in self.added_data.items():
|
for ifc_definition_id, obj in self.added_data.items():
|
||||||
if isinstance(obj, bpy.types.Object):
|
if isinstance(obj, bpy.types.Object):
|
||||||
@@ -1813,16 +1799,6 @@ class IfcImporter:
|
|||||||
):
|
):
|
||||||
return representation.Items[0].MappingTarget
|
return representation.Items[0].MappingTarget
|
||||||
|
|
||||||
def get_mesh_name(self, geometry):
|
|
||||||
representation_id = geometry.id
|
|
||||||
if "-" in representation_id:
|
|
||||||
representation_id = int(re.sub(r"\D", "", representation_id.split("-")[0]))
|
|
||||||
else:
|
|
||||||
representation_id = int(re.sub(r"\D", "", representation_id))
|
|
||||||
representation = self.file.by_id(representation_id)
|
|
||||||
context_id = representation.ContextOfItems.id() if hasattr(representation, "ContextOfItems") else 0
|
|
||||||
return "{}/{}".format(context_id, representation_id)
|
|
||||||
|
|
||||||
def create_camera(self, element, shape):
|
def create_camera(self, element, shape):
|
||||||
if hasattr(shape, "geometry"):
|
if hasattr(shape, "geometry"):
|
||||||
geometry = shape.geometry
|
geometry = shape.geometry
|
||||||
@@ -1837,7 +1813,7 @@ class IfcImporter:
|
|||||||
height = max(y) - min(y)
|
height = max(y) - min(y)
|
||||||
depth = max(z) - min(z)
|
depth = max(z) - min(z)
|
||||||
|
|
||||||
camera = bpy.data.cameras.new(self.get_mesh_name(geometry))
|
camera = bpy.data.cameras.new(tool.Loader.get_mesh_name(geometry))
|
||||||
camera.type = "ORTHO"
|
camera.type = "ORTHO"
|
||||||
camera.ortho_scale = width if width > height else height
|
camera.ortho_scale = width if width > height else height
|
||||||
camera.clip_end = depth
|
camera.clip_end = depth
|
||||||
@@ -1877,7 +1853,7 @@ class IfcImporter:
|
|||||||
else:
|
else:
|
||||||
geometry = shape
|
geometry = shape
|
||||||
|
|
||||||
curve = bpy.data.curves.new(self.get_mesh_name(geometry), type="CURVE")
|
curve = bpy.data.curves.new(tool.Loader.get_mesh_name(geometry), type="CURVE")
|
||||||
curve.dimensions = "3D"
|
curve.dimensions = "3D"
|
||||||
curve.resolution_u = 2
|
curve.resolution_u = 2
|
||||||
|
|
||||||
@@ -1903,7 +1879,7 @@ class IfcImporter:
|
|||||||
else:
|
else:
|
||||||
geometry = shape
|
geometry = shape
|
||||||
|
|
||||||
mesh = bpy.data.meshes.new(self.get_mesh_name(geometry))
|
mesh = bpy.data.meshes.new(tool.Loader.get_mesh_name(geometry))
|
||||||
|
|
||||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||||
if (
|
if (
|
||||||
@@ -2018,17 +1994,6 @@ class IfcImporter:
|
|||||||
self.added_data[element.id()] = obj
|
self.added_data[element.id()] = obj
|
||||||
IfcStore.link_element(element, obj)
|
IfcStore.link_element(element, obj)
|
||||||
|
|
||||||
def link_mesh(self, shape, mesh):
|
|
||||||
if hasattr(shape, "geometry"):
|
|
||||||
geometry = shape.geometry
|
|
||||||
else:
|
|
||||||
geometry = shape
|
|
||||||
if "-" in geometry.id:
|
|
||||||
mesh.BIMMeshProperties.ifc_definition_id = int(geometry.id.split("-")[0])
|
|
||||||
else:
|
|
||||||
# TODO: See #2002
|
|
||||||
mesh.BIMMeshProperties.ifc_definition_id = int(geometry.id.replace(",", ""))
|
|
||||||
|
|
||||||
def set_matrix_world(self, obj, matrix_world):
|
def set_matrix_world(self, obj, matrix_world):
|
||||||
obj.matrix_world = matrix_world
|
obj.matrix_world = matrix_world
|
||||||
tool.Geometry.record_object_position(obj)
|
tool.Geometry.record_object_position(obj)
|
||||||
|
|||||||
@@ -154,16 +154,13 @@ class RemoveRepresentation(bpy.types.Operator, Operator):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class UpdateRepresentation(bpy.types.Operator):
|
class UpdateRepresentation(bpy.types.Operator, Operator):
|
||||||
bl_idname = "bim.update_representation"
|
bl_idname = "bim.update_representation"
|
||||||
bl_label = "Update Representation"
|
bl_label = "Update Representation"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
obj: bpy.props.StringProperty()
|
obj: bpy.props.StringProperty()
|
||||||
ifc_representation_class: bpy.props.StringProperty()
|
ifc_representation_class: bpy.props.StringProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
if context.active_object and context.active_object.mode != "OBJECT":
|
if context.active_object and context.active_object.mode != "OBJECT":
|
||||||
# Ensure mode is object to prevent invalid mesh data causing CTD
|
# Ensure mode is object to prevent invalid mesh data causing CTD
|
||||||
|
|||||||
@@ -197,7 +197,9 @@ def update_drawing_name(ifc, drawing_tool, drawing=None, name=None):
|
|||||||
group = drawing_tool.get_drawing_group(drawing)
|
group = drawing_tool.get_drawing_group(drawing)
|
||||||
if drawing_tool.get_name(group) != name:
|
if drawing_tool.get_name(group) != name:
|
||||||
ifc.run("attribute.edit_attributes", product=group, attributes={"Name": name})
|
ifc.run("attribute.edit_attributes", product=group, attributes={"Name": name})
|
||||||
drawing_tool.set_drawing_collection_name(group, drawing_tool.get_drawing_collection(drawing))
|
collection = drawing_tool.get_drawing_collection(drawing)
|
||||||
|
if collection:
|
||||||
|
drawing_tool.set_drawing_collection_name(group, collection)
|
||||||
|
|
||||||
|
|
||||||
def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None):
|
def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None):
|
||||||
@@ -242,14 +244,13 @@ def sync_references(ifc, collector, drawing_tool, drawing=None):
|
|||||||
should_delete_existing_annotation = False
|
should_delete_existing_annotation = False
|
||||||
should_create_annotation = False
|
should_create_annotation = False
|
||||||
|
|
||||||
if annotation and (
|
if annotation:
|
||||||
not reference_obj
|
if ifc.is_deleted(annotation):
|
||||||
or ifc.is_moved(reference_obj)
|
should_delete_existing_annotation = True
|
||||||
or ifc.is_edited(reference_obj)
|
elif reference_obj and (ifc.is_moved(reference_obj) or ifc.is_edited(reference_obj)):
|
||||||
or ifc.is_deleted(reference_element)
|
should_delete_existing_annotation = True
|
||||||
or ifc.is_deleted(annotation)
|
elif not reference_obj and ifc.is_deleted(reference_element):
|
||||||
):
|
should_delete_existing_annotation = True
|
||||||
should_delete_existing_annotation = True
|
|
||||||
|
|
||||||
if reference_obj and (should_delete_existing_annotation or not annotation):
|
if reference_obj and (should_delete_existing_annotation or not annotation):
|
||||||
should_create_annotation = True
|
should_create_annotation = True
|
||||||
@@ -279,5 +280,6 @@ def select_assigned_product(drawing):
|
|||||||
def activate_drawing_view(ifc, drawing_tool, drawing):
|
def activate_drawing_view(ifc, drawing_tool, drawing):
|
||||||
camera = ifc.get_object(drawing)
|
camera = ifc.get_object(drawing)
|
||||||
if not camera:
|
if not camera:
|
||||||
return
|
camera = drawing_tool.import_drawing(drawing)
|
||||||
|
drawing_tool.import_annotations_in_group(drawing_tool.get_drawing_group(drawing))
|
||||||
drawing_tool.activate_view(camera)
|
drawing_tool.activate_view(camera)
|
||||||
|
|||||||
@@ -308,6 +308,11 @@ class Library:
|
|||||||
def set_editing_mode(cls, mode): pass
|
def set_editing_mode(cls, mode): pass
|
||||||
|
|
||||||
|
|
||||||
|
@interface
|
||||||
|
class Loader:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
class Material:
|
class Material:
|
||||||
def add_default_material_object(cls): pass
|
def add_default_material_object(cls): pass
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from blenderbim.tool.geometry import Geometry
|
|||||||
from blenderbim.tool.georeference import Georeference
|
from blenderbim.tool.georeference import Georeference
|
||||||
from blenderbim.tool.ifc import Ifc
|
from blenderbim.tool.ifc import Ifc
|
||||||
from blenderbim.tool.library import Library
|
from blenderbim.tool.library import Library
|
||||||
|
from blenderbim.tool.loader import Loader
|
||||||
from blenderbim.tool.material import Material
|
from blenderbim.tool.material import Material
|
||||||
from blenderbim.tool.misc import Misc
|
from blenderbim.tool.misc import Misc
|
||||||
from blenderbim.tool.model import Model
|
from blenderbim.tool.model import Model
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import re
|
|||||||
import bpy
|
import bpy
|
||||||
import math
|
import math
|
||||||
import bmesh
|
import bmesh
|
||||||
|
import logging
|
||||||
import mathutils
|
import mathutils
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -33,6 +34,7 @@ import blenderbim.bim.module.drawing.sheeter as sheeter
|
|||||||
import blenderbim.bim.module.drawing.scheduler as scheduler
|
import blenderbim.bim.module.drawing.scheduler as scheduler
|
||||||
import blenderbim.bim.module.drawing.annotation as annotation
|
import blenderbim.bim.module.drawing.annotation as annotation
|
||||||
import blenderbim.bim.module.drawing.helper as helper
|
import blenderbim.bim.module.drawing.helper as helper
|
||||||
|
from blenderbim.bim.module.drawing.prop import get_diagram_scales
|
||||||
|
|
||||||
|
|
||||||
class Drawing(blenderbim.core.tool.Drawing):
|
class Drawing(blenderbim.core.tool.Drawing):
|
||||||
@@ -204,7 +206,8 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_drawing_collection(cls, drawing):
|
def get_drawing_collection(cls, drawing):
|
||||||
obj = tool.Ifc.get_object(drawing)
|
obj = tool.Ifc.get_object(drawing)
|
||||||
return obj.users_collection[0]
|
if obj:
|
||||||
|
return obj.users_collection[0]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_drawing_group(cls, drawing):
|
def get_drawing_group(cls, drawing):
|
||||||
@@ -296,6 +299,83 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
if rel.is_a("IfcRelAssignsToProduct"):
|
if rel.is_a("IfcRelAssignsToProduct"):
|
||||||
return rel.RelatingProduct
|
return rel.RelatingProduct
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def import_annotations_in_group(cls, group):
|
||||||
|
elements = set(
|
||||||
|
[e for e in cls.get_group_elements(group) if e.is_a("IfcAnnotation") and e.ObjectType != "DRAWING"]
|
||||||
|
)
|
||||||
|
logger = logging.getLogger("ImportIFC")
|
||||||
|
ifc_import_settings = blenderbim.bim.import_ifc.IfcImportSettings.factory(bpy.context, None, logger)
|
||||||
|
ifc_importer = blenderbim.bim.import_ifc.IfcImporter(ifc_import_settings)
|
||||||
|
ifc_importer.file = tool.Ifc.get()
|
||||||
|
ifc_importer.calculate_unit_scale()
|
||||||
|
ifc_importer.create_generic_elements(elements)
|
||||||
|
for obj in ifc_importer.added_data.values():
|
||||||
|
tool.Collector.assign(obj)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def import_drawing(cls, drawing):
|
||||||
|
settings = ifcopenshell.geom.settings()
|
||||||
|
settings.set(settings.STRICT_TOLERANCE, True)
|
||||||
|
shape = ifcopenshell.geom.create_shape(settings, drawing)
|
||||||
|
geometry = shape.geometry
|
||||||
|
|
||||||
|
v = geometry.verts
|
||||||
|
x = [v[i] for i in range(0, len(v), 3)]
|
||||||
|
y = [v[i + 1] for i in range(0, len(v), 3)]
|
||||||
|
z = [v[i + 2] for i in range(0, len(v), 3)]
|
||||||
|
width = max(x) - min(x)
|
||||||
|
height = max(y) - min(y)
|
||||||
|
depth = max(z) - min(z)
|
||||||
|
|
||||||
|
camera = bpy.data.cameras.new(tool.Loader.get_mesh_name(geometry))
|
||||||
|
camera.type = "ORTHO"
|
||||||
|
camera.ortho_scale = width if width > height else height
|
||||||
|
camera.clip_end = depth
|
||||||
|
|
||||||
|
if width > height:
|
||||||
|
camera.BIMCameraProperties.raster_x = 1000
|
||||||
|
camera.BIMCameraProperties.raster_y = round(1000 * (height / width))
|
||||||
|
else:
|
||||||
|
camera.BIMCameraProperties.raster_x = round(1000 * (width / height))
|
||||||
|
camera.BIMCameraProperties.raster_y = 1000
|
||||||
|
|
||||||
|
psets = ifcopenshell.util.element.get_psets(drawing)
|
||||||
|
pset = psets.get("EPset_Drawing")
|
||||||
|
if pset:
|
||||||
|
if "TargetView" in pset:
|
||||||
|
camera.BIMCameraProperties.target_view = pset["TargetView"]
|
||||||
|
if "Scale" in pset:
|
||||||
|
valid_scales = [
|
||||||
|
i[0] for i in get_diagram_scales(None, bpy.context) if pset["Scale"] == i[0].split("|")[-1]
|
||||||
|
]
|
||||||
|
if valid_scales:
|
||||||
|
camera.BIMCameraProperties.diagram_scale = valid_scales[0]
|
||||||
|
else:
|
||||||
|
camera.BIMCameraProperties.diagram_scale = "CUSTOM"
|
||||||
|
camera.BIMCameraProperties.custom_diagram_scale = pset["Scale"]
|
||||||
|
if "HasUnderlay" in pset:
|
||||||
|
camera.BIMCameraProperties.has_underlay = pset["HasUnderlay"]
|
||||||
|
if "HasLinework" in pset:
|
||||||
|
camera.BIMCameraProperties.has_linework = pset["HasLinework"]
|
||||||
|
if "HasAnnotation" in pset:
|
||||||
|
camera.BIMCameraProperties.has_annotation = pset["HasAnnotation"]
|
||||||
|
|
||||||
|
tool.Loader.link_mesh(shape, camera)
|
||||||
|
|
||||||
|
obj = bpy.data.objects.new(tool.Loader.get_name(drawing), camera)
|
||||||
|
tool.Ifc.link(drawing, obj)
|
||||||
|
|
||||||
|
m = shape.transformation.matrix.data
|
||||||
|
mat = mathutils.Matrix(
|
||||||
|
([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1])
|
||||||
|
)
|
||||||
|
obj.matrix_world = mat
|
||||||
|
tool.Geometry.record_object_position(obj)
|
||||||
|
tool.Collector.assign(obj)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def import_drawings(cls):
|
def import_drawings(cls):
|
||||||
bpy.context.scene.DocProperties.drawings.clear()
|
bpy.context.scene.DocProperties.drawings.clear()
|
||||||
@@ -923,9 +1003,12 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def is_drawing_active(cls):
|
def is_drawing_active(cls):
|
||||||
camera = bpy.context.scene.camera
|
camera = bpy.context.scene.camera
|
||||||
return (camera and camera.type == "CAMERA" and
|
return (
|
||||||
camera.BIMObjectProperties.ifc_definition_id and
|
camera
|
||||||
any(a.type == 'VIEW_3D' for a in bpy.context.screen.areas))
|
and camera.type == "CAMERA"
|
||||||
|
and camera.BIMObjectProperties.ifc_definition_id
|
||||||
|
and any(a.type == "VIEW_3D" for a in bpy.context.screen.areas)
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_camera_orthographic(cls):
|
def is_camera_orthographic(cls):
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2023 Dion Moult <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# This file is part of BlenderBIM Add-on.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import re
|
||||||
|
import bpy
|
||||||
|
import ifcopenshell.util.element
|
||||||
|
import blenderbim.core.tool
|
||||||
|
import blenderbim.tool as tool
|
||||||
|
|
||||||
|
|
||||||
|
# Progressively we'll refactor loading elements into Blender objects into this
|
||||||
|
# class. This will break down the monolithic import_ifc module and allow us to
|
||||||
|
# partially load and unload objects for huge models, partial model editing, and
|
||||||
|
# supplementary objects (e.g. drawings, structural analysis models, etc).
|
||||||
|
|
||||||
|
class Loader(blenderbim.core.tool.Loader):
|
||||||
|
@classmethod
|
||||||
|
def get_mesh_name(cls, geometry):
|
||||||
|
representation_id = geometry.id
|
||||||
|
if "-" in representation_id:
|
||||||
|
representation_id = int(re.sub(r"\D", "", representation_id.split("-")[0]))
|
||||||
|
else:
|
||||||
|
representation_id = int(re.sub(r"\D", "", representation_id))
|
||||||
|
representation = tool.Ifc.get().by_id(representation_id)
|
||||||
|
context_id = representation.ContextOfItems.id() if hasattr(representation, "ContextOfItems") else 0
|
||||||
|
return "{}/{}".format(context_id, representation_id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_name(cls, element):
|
||||||
|
return "{}/{}".format(element.is_a(), element.Name)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def link_mesh(cls, shape, mesh):
|
||||||
|
geometry = shape.geometry if hasattr(shape, "geometry") else shape
|
||||||
|
if "-" in geometry.id:
|
||||||
|
mesh.BIMMeshProperties.ifc_definition_id = int(geometry.id.split("-")[0])
|
||||||
|
else:
|
||||||
|
# TODO: See #2002
|
||||||
|
mesh.BIMMeshProperties.ifc_definition_id = int(geometry.id.replace(",", ""))
|
||||||
Reference in New Issue
Block a user