Use passed context instead of bpy when available (#1607)

This commit is contained in:
Gorgious56
2021-07-29 23:08:17 +02:00
committed by GitHub
parent d2e421382b
commit 2af1ebc614
50 changed files with 549 additions and 545 deletions
@@ -17,7 +17,7 @@ class AssignObject(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects [bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
) )
relating_object = bpy.data.objects.get(self.relating_object) relating_object = bpy.data.objects.get(self.relating_object)
if not relating_object or not relating_object.BIMObjectProperties.ifc_definition_id: if not relating_object or not relating_object.BIMObjectProperties.ifc_definition_id:
@@ -40,7 +40,7 @@ class AssignObject(bpy.types.Operator):
spatial_collection = bpy.data.collections.get(related_object.name) spatial_collection = bpy.data.collections.get(related_object.name)
relating_collection = bpy.data.collections.get(relating_object.name) relating_collection = bpy.data.collections.get(relating_object.name)
if spatial_collection: if spatial_collection:
self.remove_collection(bpy.context.scene.collection, spatial_collection) self.remove_collection(context.scene.collection, spatial_collection)
for collection in bpy.data.collections: for collection in bpy.data.collections:
if collection == relating_collection: if collection == relating_collection:
if not collection.children.get(spatial_collection.name): if not collection.children.get(spatial_collection.name):
@@ -67,8 +67,8 @@ class EnableEditingAggregate(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
bpy.context.active_object.BIMObjectProperties.relating_object = None context.active_object.BIMObjectProperties.relating_object = None
bpy.context.active_object.BIMObjectProperties.is_editing_aggregate = True context.active_object.BIMObjectProperties.is_editing_aggregate = True
return {"FINISHED"} return {"FINISHED"}
@@ -79,7 +79,7 @@ class DisableEditingAggregate(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
obj.BIMObjectProperties.is_editing_aggregate = False obj.BIMObjectProperties.is_editing_aggregate = False
return {"FINISHED"} return {"FINISHED"}
@@ -94,9 +94,9 @@ class AddAggregate(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
aggregate_collection = bpy.data.collections.new("IfcElementAssembly/Assembly") aggregate_collection = bpy.data.collections.new("IfcElementAssembly/Assembly")
bpy.context.scene.collection.children.link(aggregate_collection) context.scene.collection.children.link(aggregate_collection)
aggregate = bpy.data.objects.new("Assembly", None) aggregate = bpy.data.objects.new("Assembly", None)
aggregate_collection.objects.link(aggregate) aggregate_collection.objects.link(aggregate)
bpy.ops.bim.assign_class(obj=aggregate.name, ifc_class="IfcElementAssembly") bpy.ops.bim.assign_class(obj=aggregate.name, ifc_class="IfcElementAssembly")
@@ -115,11 +115,11 @@ class GenerateGlobalId(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
index = bpy.context.active_object.BIMAttributeProperties.attributes.find("GlobalId") index = context.active_object.BIMAttributeProperties.attributes.find("GlobalId")
if index >= 0: if index >= 0:
global_id = bpy.context.active_object.BIMAttributeProperties.attributes[index] global_id = context.active_object.BIMAttributeProperties.attributes[index]
else: else:
global_id = bpy.context.active_object.BIMAttributeProperties.attributes.add() global_id = context.active_object.BIMAttributeProperties.attributes.add()
global_id.name = "GlobalId" global_id.name = "GlobalId"
global_id.data_type = "string" global_id.data_type = "string"
global_id.string_value = ifcopenshell.guid.new() global_id.string_value = ifcopenshell.guid.new()
@@ -16,7 +16,7 @@ class AuginLogin(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = bpy.context.scene.AuginProperties props = context.scene.AuginProperties
url = "https://server.auge.pro.br/API/v3/augin_rest.php/user_login" url = "https://server.auge.pro.br/API/v3/augin_rest.php/user_login"
payload = {"email": props.username, "password": props.password} payload = {"email": props.username, "password": props.password}
@@ -36,7 +36,7 @@ class AuginReset(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = bpy.context.scene.AuginProperties props = context.scene.AuginProperties
props.is_success = False props.is_success = False
return {"FINISHED"} return {"FINISHED"}
@@ -49,7 +49,7 @@ class AuginCreateNewModel(bpy.types.Operator):
def execute(self, context): def execute(self, context):
import boto3 import boto3
from botocore.config import Config from botocore.config import Config
props = bpy.context.scene.AuginProperties props = context.scene.AuginProperties
# Create project # Create project
url = "https://server.auge.pro.br/API/v3/augin_rest.php/new_model" url = "https://server.auge.pro.br/API/v3/augin_rest.php/new_model"
@@ -113,7 +113,7 @@ class AuginCreateNewModel(bpy.types.Operator):
context.scene.render.image_settings.file_format = old_file_format context.scene.render.image_settings.file_format = old_file_format
context.scene.render.filepath = old_filepath context.scene.render.filepath = old_filepath
client.upload_file(bpy.context.scene.BIMProperties.ifc_file, result["s3_bucket"], result["model_path"]) client.upload_file(context.scene.BIMProperties.ifc_file, result["s3_bucket"], result["model_path"])
client.upload_file(thumb_path, result["s3_bucket"], result["thumb_path"]) client.upload_file(thumb_path, result["s3_bucket"], result["thumb_path"])
@@ -121,8 +121,8 @@ class AuginCreateNewModel(bpy.types.Operator):
url = "https://server.auge.pro.br/API/v3/augin_rest.php/files_uploaded" url = "https://server.auge.pro.br/API/v3/augin_rest.php/files_uploaded"
payload = { payload = {
"user_token": props.token, "user_token": props.token,
"ifc_filesize": os.path.getsize(bpy.context.scene.BIMProperties.ifc_file), "ifc_filesize": os.path.getsize(context.scene.BIMProperties.ifc_file),
"model_filesize": os.path.getsize(bpy.context.scene.BIMProperties.ifc_file), "model_filesize": os.path.getsize(context.scene.BIMProperties.ifc_file),
"thumb_filesize": os.path.getsize(thumb_path), "thumb_filesize": os.path.getsize(thumb_path),
"model_upload_path": result["model_path"], "model_upload_path": result["model_path"],
"thumb_upload_path": result["thumb_path"], "thumb_upload_path": result["thumb_path"],
@@ -28,7 +28,7 @@ class BIM_PT_augin(bpy.types.Panel):
row = layout.row() row = layout.row()
row.label(text="Logged in as " + props.username) row.label(text="Logged in as " + props.username)
if not bpy.context.scene.BIMProperties.ifc_file: if not context.scene.BIMProperties.ifc_file:
row = layout.row() row = layout.row()
row.label(text="No IFC Found") row.label(text="No IFC Found")
return return
@@ -14,11 +14,11 @@ class NewBcfProject(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
bpy.context.scene.BCFProperties.is_loaded = False context.scene.BCFProperties.is_loaded = False
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
bcfxml.new_project() bcfxml.new_project()
bpy.ops.bim.load_bcf_project() bpy.ops.bim.load_bcf_project()
bpy.context.scene.BCFProperties.is_loaded = True context.scene.BCFProperties.is_loaded = True
return {"FINISHED"} return {"FINISHED"}
@@ -30,14 +30,14 @@ class LoadBcfProject(bpy.types.Operator):
filter_glob: bpy.props.StringProperty(default="*.bcf;*.bcfzip", options={"HIDDEN"}) filter_glob: bpy.props.StringProperty(default="*.bcf;*.bcfzip", options={"HIDDEN"})
def execute(self, context): def execute(self, context):
bpy.context.scene.BCFProperties.is_loaded = False context.scene.BCFProperties.is_loaded = False
if self.filepath: if self.filepath:
bcfstore.BcfStore.bcfxml = bcf.bcfxml.load(self.filepath) bcfstore.BcfStore.bcfxml = bcf.bcfxml.load(self.filepath)
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
bcfxml.get_project() bcfxml.get_project()
bpy.context.scene.BCFProperties.name = bcfxml.project.name context.scene.BCFProperties.name = bcfxml.project.name
bpy.ops.bim.load_bcf_topics() bpy.ops.bim.load_bcf_topics()
bpy.context.scene.BCFProperties.is_loaded = True context.scene.BCFProperties.is_loaded = True
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -53,11 +53,11 @@ class LoadBcfTopics(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
bcfxml.get_topics() bcfxml.get_topics()
while len(bpy.context.scene.BCFProperties.topics) > 0: while len(context.scene.BCFProperties.topics) > 0:
bpy.context.scene.BCFProperties.topics.remove(0) context.scene.BCFProperties.topics.remove(0)
index = 0 index = 0
for topic_guid in bcfxml.topics.keys(): for topic_guid in bcfxml.topics.keys():
new = bpy.context.scene.BCFProperties.topics.add() new = context.scene.BCFProperties.topics.add()
bpy.ops.bim.load_bcf_topic(topic_guid = topic_guid, topic_index = index) bpy.ops.bim.load_bcf_topic(topic_guid = topic_guid, topic_index = index)
index += 1 index += 1
return {"FINISHED"} return {"FINISHED"}
@@ -73,7 +73,7 @@ class LoadBcfTopic(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
topic = bcfxml.get_topic(self.topic_guid) topic = bcfxml.get_topic(self.topic_guid)
new = bpy.context.scene.BCFProperties.topics[self.topic_index] new = context.scene.BCFProperties.topics[self.topic_index]
data_map = { data_map = {
"name": topic.guid, "name": topic.guid,
"title": topic.title, "title": topic.title,
@@ -143,7 +143,7 @@ class LoadBcfComments(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
bcfxml.get_comments(self.topic_guid) bcfxml.get_comments(self.topic_guid)
blender_topic = bpy.context.scene.BCFProperties.topics.get(self.topic_guid) blender_topic = context.scene.BCFProperties.topics.get(self.topic_guid)
while len(blender_topic.comments) > 0: while len(blender_topic.comments) > 0:
blender_topic.comments.remove(0) blender_topic.comments.remove(0)
for comment in bcfxml.topics[self.topic_guid].comments.values(): for comment in bcfxml.topics[self.topic_guid].comments.values():
@@ -170,7 +170,7 @@ class EditBcfProjectName(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
bcfxml.project.name = bpy.context.scene.BCFProperties.name bcfxml.project.name = context.scene.BCFProperties.name
bcfxml.edit_project() bcfxml.edit_project()
return {"FINISHED"} return {"FINISHED"}
@@ -182,7 +182,7 @@ class EditBcfAuthor(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
bcfxml.author = bpy.context.scene.BCFProperties.author bcfxml.author = context.scene.BCFProperties.author
return {"FINISHED"} return {"FINISHED"}
@@ -192,7 +192,7 @@ class EditBcfTopicName(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
@@ -207,7 +207,7 @@ class EditBcfTopic(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
@@ -250,7 +250,7 @@ class AddBcfTopic(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
bcfxml.add_topic() bcfxml.add_topic()
new = bpy.context.scene.BCFProperties.topics.add() new = context.scene.BCFProperties.topics.add()
new.name = "New Topic" new.name = "New Topic"
bpy.ops.bim.load_bcf_topics() bpy.ops.bim.load_bcf_topics()
return {"FINISHED"} return {"FINISHED"}
@@ -263,7 +263,7 @@ class AddBcfBimSnippet(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
bim_snippet = bcf.v2.data.BimSnippet() bim_snippet = bcf.v2.data.BimSnippet()
@@ -282,7 +282,7 @@ class AddBcfRelatedTopic(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
related_topic = None related_topic = None
for topic in bcfxml.topics.values(): for topic in bcfxml.topics.values():
@@ -306,7 +306,7 @@ class AddBcfHeaderFile(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
header_file = bcf.v2.data.HeaderFile() header_file = bcf.v2.data.HeaderFile()
@@ -329,9 +329,9 @@ class ViewBcfTopic(bpy.types.Operator):
topic_guid: bpy.props.StringProperty() topic_guid: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
for index, topic in enumerate(bpy.context.scene.BCFProperties.topics): for index, topic in enumerate(context.scene.BCFProperties.topics):
if topic.guid.lower() == self.topic_guid.lower(): if topic.guid.lower() == self.topic_guid.lower():
bpy.context.scene.BCFProperties.active_topic_index = index context.scene.BCFProperties.active_topic_index = index
return {"FINISHED"} return {"FINISHED"}
@@ -341,44 +341,44 @@ class AddBcfViewpoint(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
if not bpy.context.scene.camera: if not context.scene.camera:
return {"FINISHED"} return {"FINISHED"}
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
viewpoint = bcf.v2.data.Viewpoint() viewpoint = bcf.v2.data.Viewpoint()
if bpy.context.scene.camera.data.type == "ORTHO": if context.scene.camera.data.type == "ORTHO":
camera = bcf.v2.data.OrthogonalCamera() camera = bcf.v2.data.OrthogonalCamera()
camera.view_to_world_scale = bpy.context.scene.camera.data.ortho_scale camera.view_to_world_scale = context.scene.camera.data.ortho_scale
viewpoint.orthogonal_camera = camera viewpoint.orthogonal_camera = camera
elif bpy.context.scene.camera.data.type == "PERSP": elif context.scene.camera.data.type == "PERSP":
camera = bcf.v2.data.PerspectiveCamera() camera = bcf.v2.data.PerspectiveCamera()
camera.field_of_view = degrees(bpy.context.scene.camera.data.angle) camera.field_of_view = degrees(context.scene.camera.data.angle)
viewpoint.perspective_camera = camera viewpoint.perspective_camera = camera
camera.camera_view_point.x = bpy.context.scene.camera.location.x camera.camera_view_point.x = context.scene.camera.location.x
camera.camera_view_point.y = bpy.context.scene.camera.location.y camera.camera_view_point.y = context.scene.camera.location.y
camera.camera_view_point.z = bpy.context.scene.camera.location.z camera.camera_view_point.z = context.scene.camera.location.z
direction = bpy.context.scene.camera.matrix_world.to_quaternion() @ Vector((0.0, 0.0, -1.0)) direction = context.scene.camera.matrix_world.to_quaternion() @ Vector((0.0, 0.0, -1.0))
camera.camera_direction.x = direction.x camera.camera_direction.x = direction.x
camera.camera_direction.y = direction.y camera.camera_direction.y = direction.y
camera.camera_direction.z = direction.z camera.camera_direction.z = direction.z
up = bpy.context.scene.camera.matrix_world.to_quaternion() @ Vector((0.0, 1.0, 0.0)) up = context.scene.camera.matrix_world.to_quaternion() @ Vector((0.0, 1.0, 0.0))
camera.camera_up_vector.x = up.x camera.camera_up_vector.x = up.x
camera.camera_up_vector.y = up.y camera.camera_up_vector.y = up.y
camera.camera_up_vector.z = up.z camera.camera_up_vector.z = up.z
old_file_format = bpy.context.scene.render.image_settings.file_format old_file_format = context.scene.render.image_settings.file_format
bpy.context.scene.render.image_settings.file_format = "PNG" context.scene.render.image_settings.file_format = "PNG"
old_filepath = bpy.context.scene.render.filepath old_filepath = context.scene.render.filepath
bpy.context.scene.render.filepath = os.path.join(bpy.context.scene.BIMProperties.data_dir, "snapshot.png") context.scene.render.filepath = os.path.join(context.scene.BIMProperties.data_dir, "snapshot.png")
bpy.ops.render.opengl(write_still=True) bpy.ops.render.opengl(write_still=True)
viewpoint.snapshot = bpy.context.scene.render.filepath viewpoint.snapshot = context.scene.render.filepath
bcfxml.add_viewpoint(topic, viewpoint) bcfxml.add_viewpoint(topic, viewpoint)
bpy.context.scene.render.filepath = old_filepath context.scene.render.filepath = old_filepath
bpy.context.scene.render.image_settings.file_format = old_file_format context.scene.render.image_settings.file_format = old_file_format
props.active_topic_index = props.active_topic_index # refreshes the BCF Topic props.active_topic_index = props.active_topic_index # refreshes the BCF Topic
return {"FINISHED"} return {"FINISHED"}
@@ -390,7 +390,7 @@ class RemoveBcfViewpoint(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
viewpoint_guid = blender_topic.viewpoints viewpoint_guid = blender_topic.viewpoints
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
@@ -407,7 +407,7 @@ class RemoveBcfFile(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
bcfxml.delete_file(topic, self.index) bcfxml.delete_file(topic, self.index)
@@ -422,7 +422,7 @@ class AddBcfReferenceLink(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
if not blender_topic.reference_link: if not blender_topic.reference_link:
@@ -441,7 +441,7 @@ class AddBcfDocumentReference(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
if not blender_topic.document_reference: if not blender_topic.document_reference:
@@ -463,7 +463,7 @@ class AddBcfLabel(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
if not blender_topic.label: if not blender_topic.label:
@@ -483,7 +483,7 @@ class EditBcfReferenceLinks(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
for index, reference_link in enumerate(topic.reference_links): for index, reference_link in enumerate(topic.reference_links):
@@ -501,7 +501,7 @@ class EditBcfLabels(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
for index, label in enumerate(blender_topic.labels): for index, label in enumerate(blender_topic.labels):
@@ -520,7 +520,7 @@ class RemoveBcfReferenceLink(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
del topic.reference_links[self.index] del topic.reference_links[self.index]
@@ -537,7 +537,7 @@ class RemoveBcfLabel(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
del topic.labels[self.index] del topic.labels[self.index]
@@ -553,7 +553,7 @@ class RemoveBcfBimSnippet(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
bcfxml.delete_bim_snippet(topic) bcfxml.delete_bim_snippet(topic)
@@ -571,7 +571,7 @@ class RemoveBcfDocumentReference(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
bcfxml.delete_document_reference(topic, self.index) bcfxml.delete_document_reference(topic, self.index)
@@ -587,7 +587,7 @@ class RemoveBcfRelatedTopic(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
del topic.related_topics[self.index] del topic.related_topics[self.index]
@@ -604,7 +604,7 @@ class RemoveBcfComment(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
bcfxml.delete_comment(self.comment_guid, topic) bcfxml.delete_comment(self.comment_guid, topic)
@@ -620,7 +620,7 @@ class EditBcfComment(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
blender_comment = blender_topic.comments.get(self.comment_guid) blender_comment = blender_topic.comments.get(self.comment_guid)
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
@@ -639,7 +639,7 @@ class AddBcfComment(bpy.types.Operator):
def execute(self, context): def execute(self, context):
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
if not blender_topic.comment: if not blender_topic.comment:
@@ -662,7 +662,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
blender_topic = props.topics[props.active_topic_index] blender_topic = props.topics[props.active_topic_index]
topic = bcfxml.topics[blender_topic.name] topic = bcfxml.topics[blender_topic.name]
if not topic.viewpoints: if not topic.viewpoints:
@@ -673,11 +673,11 @@ class ActivateBcfViewpoint(bpy.types.Operator):
obj = bpy.data.objects.get("Viewpoint") obj = bpy.data.objects.get("Viewpoint")
if not obj: if not obj:
obj = bpy.data.objects.new("Viewpoint", bpy.data.cameras.new("Viewpoint")) obj = bpy.data.objects.new("Viewpoint", bpy.data.cameras.new("Viewpoint"))
bpy.context.scene.collection.objects.link(obj) context.scene.collection.objects.link(obj)
bpy.context.scene.camera = obj context.scene.camera = obj
cam_width = bpy.context.scene.render.resolution_x cam_width = context.scene.render.resolution_x
cam_height = bpy.context.scene.render.resolution_y cam_height = context.scene.render.resolution_y
cam_aspect = cam_width / cam_height cam_aspect = cam_width / cam_height
if viewpoint.snapshot: if viewpoint.snapshot:
@@ -697,7 +697,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
else: else:
background.frame_method = "CROP" background.frame_method = "CROP"
background.display_depth = "FRONT" background.display_depth = "FRONT"
area = next(area for area in bpy.context.screen.areas if area.type == "VIEW_3D") area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
area.spaces[0].region_3d.view_perspective = "CAMERA" area.spaces[0].region_3d.view_perspective = "CAMERA"
if viewpoint.orthogonal_camera: if viewpoint.orthogonal_camera:
@@ -719,13 +719,13 @@ class ActivateBcfViewpoint(bpy.types.Operator):
if gp: if gp:
bpy.data.grease_pencils.remove(gp) bpy.data.grease_pencils.remove(gp)
if viewpoint.lines: if viewpoint.lines:
self.draw_lines(viewpoint) self.draw_lines(viewpoint, context)
self.delete_clipping_planes() self.delete_clipping_planes(context)
if viewpoint.clipping_planes: if viewpoint.clipping_planes:
self.create_clipping_planes(viewpoint) self.create_clipping_planes(viewpoint)
self.delete_bitmaps() self.delete_bitmaps(context)
if viewpoint.bitmaps: if viewpoint.bitmaps:
self.create_bitmaps(bcfxml, viewpoint, topic) self.create_bitmaps(bcfxml, viewpoint, topic)
@@ -776,9 +776,9 @@ class ActivateBcfViewpoint(bpy.types.Operator):
if global_id in global_id_colours: if global_id in global_id_colours:
obj.color = self.hex_to_rgb(global_id_colours[global_id]) obj.color = self.hex_to_rgb(global_id_colours[global_id])
def draw_lines(self, viewpoint): def draw_lines(self, viewpoint, context):
gp = bpy.data.grease_pencils.new("BCF") gp = bpy.data.grease_pencils.new("BCF")
scene = bpy.context.scene scene = context.scene
scene.grease_pencil = gp scene.grease_pencil = gp
scene.frame_set(1) scene.frame_set(1)
layer = gp.layers.new("BCF Annotation", set_active=True) layer = gp.layers.new("BCF Annotation", set_active=True)
@@ -808,19 +808,19 @@ class ActivateBcfViewpoint(bpy.types.Operator):
) )
n += 1 n += 1
def delete_clipping_planes(self): def delete_clipping_planes(self, context):
collection = bpy.data.collections.get("Sections") collection = bpy.data.collections.get("Sections")
if not collection: if not collection:
return return
for section in collection.objects: for section in collection.objects:
bpy.context.view_layer.objects.active = section context.view_layer.objects.active = section
bpy.ops.bim.remove_section_plane() bpy.ops.bim.remove_section_plane()
def delete_bitmaps(self): def delete_bitmaps(self, context):
collection = bpy.data.collections.get("Bitmaps") collection = bpy.data.collections.get("Bitmaps")
if not collection: if not collection:
collection = bpy.data.collections.new("Bitmaps") collection = bpy.data.collections.new("Bitmaps")
bpy.context.scene.collection.children.link(collection) context.scene.collection.children.link(collection)
for bitmap in collection.objects: for bitmap in collection.objects:
bpy.data.objects.remove(bitmap) bpy.data.objects.remove(bitmap)
@@ -860,7 +860,7 @@ class OpenBcfReferenceLink(bpy.types.Operator):
index: bpy.props.IntProperty() index: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
webbrowser.open(bpy.context.scene.BCFProperties.topic_links[self.index].name) webbrowser.open(context.scene.BCFProperties.topic_links[self.index].name)
return {"FINISHED"} return {"FINISHED"}
@@ -872,7 +872,7 @@ class SelectBcfHeaderFile(bpy.types.Operator):
def execute(self, context): def execute(self, context):
if self.filepath: if self.filepath:
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
topic = props.topics[props.active_topic_index] topic = props.topics[props.active_topic_index]
topic.file_reference = self.filepath topic.file_reference = self.filepath
return {"FINISHED"} return {"FINISHED"}
@@ -890,7 +890,7 @@ class SelectBcfBimSnippetReference(bpy.types.Operator):
def execute(self, context): def execute(self, context):
if self.filepath: if self.filepath:
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
topic = props.topics[props.active_topic_index] topic = props.topics[props.active_topic_index]
topic.bim_snippet_reference = self.filepath topic.bim_snippet_reference = self.filepath
return {"FINISHED"} return {"FINISHED"}
@@ -908,7 +908,7 @@ class SelectBcfDocumentReference(bpy.types.Operator):
def execute(self, context): def execute(self, context):
if self.filepath: if self.filepath:
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
topic = props.topics[props.active_topic_index] topic = props.topics[props.active_topic_index]
topic.document_reference = self.filepath topic.document_reference = self.filepath
return {"FINISHED"} return {"FINISHED"}
@@ -23,37 +23,37 @@ def purge():
def updateBcfReferenceLink(self, context): def updateBcfReferenceLink(self, context):
if bpy.context.scene.BCFProperties.is_loaded: if context.scene.BCFProperties.is_loaded:
bpy.ops.bim.edit_bcf_reference_links() bpy.ops.bim.edit_bcf_reference_links()
def updateBcfLabel(self, context): def updateBcfLabel(self, context):
if bpy.context.scene.BCFProperties.is_loaded: if context.scene.BCFProperties.is_loaded:
bpy.ops.bim.edit_bcf_labels() bpy.ops.bim.edit_bcf_labels()
def updateBcfProjectName(self, context): def updateBcfProjectName(self, context):
if bpy.context.scene.BCFProperties.is_loaded: if context.scene.BCFProperties.is_loaded:
bpy.ops.bim.edit_bcf_project_name() bpy.ops.bim.edit_bcf_project_name()
def updateBcfAuthor(self, context): def updateBcfAuthor(self, context):
if bpy.context.scene.BCFProperties.is_loaded: if context.scene.BCFProperties.is_loaded:
bpy.ops.bim.edit_bcf_author() bpy.ops.bim.edit_bcf_author()
def updateBcfTopicName(self, context): def updateBcfTopicName(self, context):
if bpy.context.scene.BCFProperties.is_loaded: if context.scene.BCFProperties.is_loaded:
bpy.ops.bim.edit_bcf_topic_name() bpy.ops.bim.edit_bcf_topic_name()
def updateBcfTopicIsEditable(self, context): def updateBcfTopicIsEditable(self, context):
if bpy.context.scene.BCFProperties.is_loaded and not self.is_editable: if context.scene.BCFProperties.is_loaded and not self.is_editable:
bpy.ops.bim.edit_bcf_topic() bpy.ops.bim.edit_bcf_topic()
def updateBcfCommentIsEditable(self, context): def updateBcfCommentIsEditable(self, context):
if bpy.context.scene.BCFProperties.is_loaded and not self.is_editable: if context.scene.BCFProperties.is_loaded and not self.is_editable:
bpy.ops.bim.edit_bcf_comment(comment_guid = self.name) bpy.ops.bim.edit_bcf_comment(comment_guid = self.name)
@@ -61,7 +61,7 @@ def refreshBcfTopic(self, context):
global bcfviewpoints_enum global bcfviewpoints_enum
bcfviewpoints_enum = None bcfviewpoints_enum = None
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
topic = props.topics[props.active_topic_index] topic = props.topics[props.active_topic_index]
header = bcfxml.get_header(topic.name) header = bcfxml.get_header(topic.name)
@@ -80,7 +80,7 @@ def getBcfViewpoints(self, context):
global bcfviewpoints_enum global bcfviewpoints_enum
if bcfviewpoints_enum is None: if bcfviewpoints_enum is None:
bcfviewpoints_enum = [] bcfviewpoints_enum = []
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
bcfxml = bcfstore.BcfStore.get_bcfxml() bcfxml = bcfstore.BcfStore.get_bcfxml()
topic = props.topics[props.active_topic_index] topic = props.topics[props.active_topic_index]
viewpoints = bcfxml.get_viewpoints(topic.name) viewpoints = bcfxml.get_viewpoints(topic.name)
@@ -17,7 +17,7 @@ class BIM_PT_bcf(Panel):
layout.use_property_decorate = False layout.use_property_decorate = False
scene = context.scene scene = context.scene
props = bpy.context.scene.BCFProperties props = scene.BCFProperties
row = layout.row(align=True) row = layout.row(align=True)
row.operator("bim.new_bcf_project", text="New Project") row.operator("bim.new_bcf_project", text="New Project")
@@ -34,7 +34,7 @@ class BIM_PT_bcf(Panel):
row = layout.row() row = layout.row()
row.prop(props, "author") row.prop(props, "author")
props = bpy.context.scene.BCFProperties props = context.scene.BCFProperties
row = layout.row() row = layout.row()
row.template_list("BIM_UL_topics", "", props, "topics", props, "active_topic_index") row.template_list("BIM_UL_topics", "", props, "topics", props, "active_topic_index")
col = row.column(align=True) col = row.column(align=True)
@@ -93,7 +93,7 @@ class BIM_PT_bcf_metadata(Panel):
layout.use_property_decorate = False layout.use_property_decorate = False
scene = context.scene scene = context.scene
props = bpy.context.scene.BCFProperties props = scene.BCFProperties
if props.active_topic_index >= len(props.topics): if props.active_topic_index >= len(props.topics):
layout.label(text="No BCF project is loaded") layout.label(text="No BCF project is loaded")
@@ -236,7 +236,7 @@ class BIM_PT_bcf_comments(Panel):
layout.use_property_decorate = False layout.use_property_decorate = False
scene = context.scene scene = context.scene
props = bpy.context.scene.BCFProperties props = scene.BCFProperties
if props.active_topic_index >= len(props.topics): if props.active_topic_index >= len(props.topics):
layout.label(text="No BCF project is loaded") layout.label(text="No BCF project is loaded")
@@ -52,11 +52,11 @@ class BIMTesterPurge(bpy.types.Operator):
def execute(self, context): def execute(self, context):
filename = os.path.join( filename = os.path.join(
bpy.context.scene.BimTesterProperties.features_dir, context.scene.BimTesterProperties.features_dir,
bpy.context.scene.BimTesterProperties.features_file + ".feature", context.scene.BimTesterProperties.features_file + ".feature",
) )
cwd = os.getcwd() cwd = os.getcwd()
os.chdir(bpy.context.scene.BimTesterProperties.features_dir) os.chdir(context.scene.BimTesterProperties.features_dir)
bimtester.clean.TestPurger().purge() bimtester.clean.TestPurger().purge()
os.chdir(cwd) os.chdir(cwd)
return {"FINISHED"} return {"FINISHED"}
@@ -71,7 +71,7 @@ class SelectFeature(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.BimTesterProperties.feature = self.filepath context.scene.BimTesterProperties.feature = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -88,7 +88,7 @@ class SelectSteps(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.BimTesterProperties.steps = self.filepath context.scene.BimTesterProperties.steps = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -120,14 +120,14 @@ class RejectElement(bpy.types.Operator):
def execute(self, context): def execute(self, context):
lines = [] lines = []
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
lines.append( lines.append(
" * The element {} should not exist because {}".format( " * The element {} should not exist because {}".format(
self.file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId, self.file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId,
bpy.context.scene.BimTesterProperties.qa_reject_element_reason, context.scene.BimTesterProperties.qa_reject_element_reason,
) )
) )
QAHelper.append_to_scenario(lines) QAHelper.append_to_scenario(lines, context)
return {"FINISHED"} return {"FINISHED"}
@@ -138,12 +138,12 @@ class ApproveClass(bpy.types.Operator):
def execute(self, context): def execute(self, context):
lines = [] lines = []
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
lines.append(" * The element {} is an {}".format(element.GlobalId, element.is_a())) lines.append(" * The element {} is an {}".format(element.GlobalId, element.is_a()))
QAHelper.append_to_scenario(lines) QAHelper.append_to_scenario(lines, context)
return {"FINISHED"} return {"FINISHED"}
@@ -154,16 +154,16 @@ class RejectClass(bpy.types.Operator):
def execute(self, context): def execute(self, context):
lines = [] lines = []
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
lines.append( lines.append(
" * The element {} is an {}".format( " * The element {} is an {}".format(
self.file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId, self.file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId,
bpy.context.scene.BimTesterProperties.audit_ifc_class, context.scene.BimTesterProperties.audit_ifc_class,
) )
) )
QAHelper.append_to_scenario(lines) QAHelper.append_to_scenario(lines, context)
return {"FINISHED"} return {"FINISHED"}
@@ -175,7 +175,7 @@ class SelectAudited(bpy.types.Operator):
def execute(self, context): def execute(self, context):
audited_global_ids = [] audited_global_ids = []
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for filename in Path(bpy.context.scene.BimTesterProperties.features_dir).glob("*.feature"): for filename in Path(context.scene.BimTesterProperties.features_dir).glob("*.feature"):
with open(filename, "r") as feature_file: with open(filename, "r") as feature_file:
lines = feature_file.readlines() lines = feature_file.readlines()
for line in lines: for line in lines:
@@ -183,7 +183,7 @@ class SelectAudited(bpy.types.Operator):
for word in words: for word in words:
if self.is_a_global_id(word): if self.is_a_global_id(word):
audited_global_ids.append(word) audited_global_ids.append(word)
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
if self.file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId in audited_global_ids: if self.file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId in audited_global_ids:
@@ -196,10 +196,10 @@ class SelectAudited(bpy.types.Operator):
class QAHelper: class QAHelper:
@classmethod @classmethod
def append_to_scenario(cls, lines): def append_to_scenario(cls, lines, context):
filename = os.path.join( filename = os.path.join(
bpy.context.scene.BimTesterProperties.features_dir, context.scene.BimTesterProperties.features_dir,
bpy.context.scene.BimTesterProperties.features_file + ".feature", context.scene.BimTesterProperties.features_file + ".feature",
) )
if os.path.exists(filename + "~"): if os.path.exists(filename + "~"):
os.remove(filename + "~") os.remove(filename + "~")
@@ -210,7 +210,7 @@ class QAHelper:
for source_line in source: for source_line in source:
if ( if (
"Scenario: " in source_line "Scenario: " in source_line
and bpy.context.scene.BimTesterProperties.scenario == source_line.strip()[len("Scenario: ") :] and context.scene.BimTesterProperties.scenario == source_line.strip()[len("Scenario: ") :]
): ):
is_in_scenario = True is_in_scenario = True
elif is_in_scenario: elif is_in_scenario:
@@ -23,7 +23,7 @@ class ExportClashSets(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.filepath = bpy.path.ensure_ext(self.filepath, ".json") self.filepath = bpy.path.ensure_ext(self.filepath, ".json")
clash_sets = [] clash_sets = []
for clash_set in bpy.context.scene.BIMClashProperties.clash_sets: for clash_set in context.scene.BIMClashProperties.clash_sets:
self.a = [] self.a = []
self.b = [] self.b = []
for ab in ["a", "b"]: for ab in ["a", "b"]:
@@ -56,7 +56,7 @@ class ImportClashSets(bpy.types.Operator):
with open(self.filepath) as f: with open(self.filepath) as f:
clash_sets = json.load(f) clash_sets = json.load(f)
for clash_set in clash_sets: for clash_set in clash_sets:
new = bpy.context.scene.BIMClashProperties.clash_sets.add() new = context.scene.BIMClashProperties.clash_sets.add()
new.name = clash_set["name"] new.name = clash_set["name"]
new.tolerance = clash_set["tolerance"] new.tolerance = clash_set["tolerance"]
for clash_source in clash_set["a"]: for clash_source in clash_set["a"]:
@@ -81,7 +81,7 @@ class AddClashSet(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
new = bpy.context.scene.BIMClashProperties.clash_sets.add() new = context.scene.BIMClashProperties.clash_sets.add()
new.name = "New Clash Set" new.name = "New Clash Set"
new.tolerance = 0.01 new.tolerance = 0.01
return {"FINISHED"} return {"FINISHED"}
@@ -94,7 +94,7 @@ class RemoveClashSet(bpy.types.Operator):
index: bpy.props.IntProperty() index: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
bpy.context.scene.BIMClashProperties.clash_sets.remove(self.index) context.scene.BIMClashProperties.clash_sets.remove(self.index)
return {"FINISHED"} return {"FINISHED"}
@@ -105,7 +105,7 @@ class AddClashSource(bpy.types.Operator):
group: bpy.props.StringProperty() group: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
clash_set = bpy.context.scene.BIMClashProperties.clash_sets[bpy.context.scene.BIMClashProperties.active_clash_set_index] clash_set = context.scene.BIMClashProperties.clash_sets[context.scene.BIMClashProperties.active_clash_set_index]
source = getattr(clash_set, self.group).add() source = getattr(clash_set, self.group).add()
return {"FINISHED"} return {"FINISHED"}
@@ -118,7 +118,7 @@ class RemoveClashSource(bpy.types.Operator):
group: bpy.props.StringProperty() group: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
clash_set = bpy.context.scene.BIMClashProperties.clash_sets[bpy.context.scene.BIMClashProperties.active_clash_set_index] clash_set = context.scene.BIMClashProperties.clash_sets[context.scene.BIMClashProperties.active_clash_set_index]
getattr(clash_set, self.group).remove(self.index) getattr(clash_set, self.group).remove(self.index)
return {"FINISHED"} return {"FINISHED"}
@@ -133,7 +133,7 @@ class SelectClashSource(bpy.types.Operator):
group: bpy.props.StringProperty() group: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
clash_set = bpy.context.scene.BIMClashProperties.clash_sets[bpy.context.scene.BIMClashProperties.active_clash_set_index] clash_set = context.scene.BIMClashProperties.clash_sets[context.scene.BIMClashProperties.active_clash_set_index]
getattr(clash_set, self.group)[self.index].name = self.filepath getattr(clash_set, self.group)[self.index].name = self.filepath
return {"FINISHED"} return {"FINISHED"}
@@ -149,7 +149,7 @@ class SelectClashResults(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.BIMClashProperties.clash_results_path = self.filepath context.scene.BIMClashProperties.clash_results_path = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -164,7 +164,7 @@ class SelectSmartGroupedClashesPath(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.BIMClashProperties.smart_grouped_clashes_path = self.filepath context.scene.BIMClashProperties.smart_grouped_clashes_path = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -196,32 +196,32 @@ class ExecuteIfcClash(bpy.types.Operator):
settings.logger.setLevel(logging.DEBUG) settings.logger.setLevel(logging.DEBUG)
ifc_clasher = ifcclash.IfcClasher(settings) ifc_clasher = ifcclash.IfcClasher(settings)
if bpy.context.scene.BIMClashProperties.should_create_clash_snapshots: if context.scene.BIMClashProperties.should_create_clash_snapshots:
def get_viewpoint_snapshot(self, viewpoint, mat): def get_viewpoint_snapshot(self, viewpoint, mat):
camera = bpy.data.objects.get("IFC Clash Camera") camera = bpy.data.objects.get("IFC Clash Camera")
if not camera: if not camera:
camera = bpy.data.objects.new("IFC Clash Camera", bpy.data.cameras.new("IFC Clash Camera")) camera = bpy.data.objects.new("IFC Clash Camera", bpy.data.cameras.new("IFC Clash Camera"))
bpy.context.scene.collection.objects.link(camera) context.scene.collection.objects.link(camera)
camera.matrix_world = Matrix(mat) camera.matrix_world = Matrix(mat)
bpy.context.scene.camera = camera context.scene.camera = camera
camera.data.angle = radians(60) camera.data.angle = radians(60)
area = next(area for area in bpy.context.screen.areas if area.type == "VIEW_3D") area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
area.spaces[0].region_3d.view_perspective = "CAMERA" area.spaces[0].region_3d.view_perspective = "CAMERA"
area.spaces[0].shading.show_xray = True area.spaces[0].shading.show_xray = True
bpy.context.scene.render.resolution_x = 480 context.scene.render.resolution_x = 480
bpy.context.scene.render.resolution_y = 270 context.scene.render.resolution_y = 270
bpy.context.scene.render.image_settings.file_format = "PNG" context.scene.render.image_settings.file_format = "PNG"
bpy.context.scene.render.filepath = os.path.join( context.scene.render.filepath = os.path.join(
bpy.context.scene.BIMProperties.data_dir, "snapshot.png" context.scene.BIMProperties.data_dir, "snapshot.png"
) )
bpy.ops.render.opengl(write_still=True) bpy.ops.render.opengl(write_still=True)
return bpy.context.scene.render.filepath return context.scene.render.filepath
ifcclash.IfcClasher.get_viewpoint_snapshot = get_viewpoint_snapshot ifcclash.IfcClasher.get_viewpoint_snapshot = get_viewpoint_snapshot
ifc_clasher.clash_sets = [] ifc_clasher.clash_sets = []
for clash_set in bpy.context.scene.BIMClashProperties.clash_sets: for clash_set in context.scene.BIMClashProperties.clash_sets:
self.a = [] self.a = []
self.b = [] self.b = []
for ab in ["a", "b"]: for ab in ["a", "b"]:
@@ -256,8 +256,8 @@ class SelectIfcClashResults(bpy.types.Operator):
self.filepath = bpy.path.ensure_ext(self.filepath, ".json") self.filepath = bpy.path.ensure_ext(self.filepath, ".json")
with open(self.filepath) as f: with open(self.filepath) as f:
clash_sets = json.load(f) clash_sets = json.load(f)
clash_set_name = bpy.context.scene.BIMClashProperties.clash_sets[ clash_set_name = context.scene.BIMClashProperties.clash_sets[
bpy.context.scene.BIMClashProperties.active_clash_set_index context.scene.BIMClashProperties.active_clash_set_index
].name ].name
global_ids = [] global_ids = []
for clash_set in clash_sets: for clash_set in clash_sets:
@@ -268,7 +268,7 @@ class SelectIfcClashResults(bpy.types.Operator):
return {"CANCELLED"} return {"CANCELLED"}
for clash in clash_set["clashes"].values(): for clash in clash_set["clashes"].values():
global_ids.extend([clash["a_global_id"], clash["b_global_id"]]) global_ids.extend([clash["a_global_id"], clash["b_global_id"]])
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
@@ -287,7 +287,7 @@ class SmartClashGroup(bpy.types.Operator):
import ifcclash import ifcclash
settings = ifcclash.IfcClashSettings() settings = ifcclash.IfcClashSettings()
self.filepath = bpy.path.ensure_ext(bpy.context.scene.BIMClashProperties.clash_results_path, ".json") self.filepath = bpy.path.ensure_ext(context.scene.BIMClashProperties.clash_results_path, ".json")
settings.output = self.filepath settings.output = self.filepath
settings.logger = logging.getLogger("Clash") settings.logger = logging.getLogger("Clash")
settings.logger.setLevel(logging.DEBUG) settings.logger.setLevel(logging.DEBUG)
@@ -297,21 +297,21 @@ class SmartClashGroup(bpy.types.Operator):
clash_sets = json.load(f) clash_sets = json.load(f)
# execute the smart grouping # execute the smart grouping
save_path = bpy.path.ensure_ext(bpy.context.scene.BIMClashProperties.smart_grouped_clashes_path, ".json") save_path = bpy.path.ensure_ext(context.scene.BIMClashProperties.smart_grouped_clashes_path, ".json")
smart_grouped_clashes = ifc_clasher.smart_group_clashes( smart_grouped_clashes = ifc_clasher.smart_group_clashes(
clash_sets, bpy.context.scene.BIMClashProperties.smart_clash_grouping_max_distance clash_sets, context.scene.BIMClashProperties.smart_clash_grouping_max_distance
) )
# save smart_groups to json # save smart_groups to json
with open(save_path, "w") as f: with open(save_path, "w") as f:
f.write(json.dumps(smart_grouped_clashes)) f.write(json.dumps(smart_grouped_clashes))
clash_set_name = bpy.context.scene.BIMClashProperties.clash_sets[ clash_set_name = context.scene.BIMClashProperties.clash_sets[
bpy.context.scene.BIMClashProperties.active_clash_set_index context.scene.BIMClashProperties.active_clash_set_index
].name ].name
# Reset the list of smart_clash_groups for the UI # Reset the list of smart_clash_groups for the UI
bpy.context.scene.BIMClashProperties.smart_clash_groups.clear() context.scene.BIMClashProperties.smart_clash_groups.clear()
for clash_set, smart_groups in smart_grouped_clashes.items(): for clash_set, smart_groups in smart_grouped_clashes.items():
# Only select the clashes that correspond to the actively selected IFC Clash Set # Only select the clashes that correspond to the actively selected IFC Clash Set
@@ -319,7 +319,7 @@ class SmartClashGroup(bpy.types.Operator):
continue continue
else: else:
for smart_group, global_id_pairs in smart_groups[0].items(): for smart_group, global_id_pairs in smart_groups[0].items():
new_group = bpy.context.scene.BIMClashProperties.smart_clash_groups.add() new_group = context.scene.BIMClashProperties.smart_clash_groups.add()
new_group.number = f"{smart_group}" new_group.number = f"{smart_group}"
for pair in global_id_pairs: for pair in global_id_pairs:
@@ -336,17 +336,17 @@ class LoadSmartGroupsForActiveClashSet(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
smart_groups_path = bpy.path.ensure_ext(bpy.context.scene.BIMClashProperties.smart_grouped_clashes_path, ".json") smart_groups_path = bpy.path.ensure_ext(context.scene.BIMClashProperties.smart_grouped_clashes_path, ".json")
clash_set_name = bpy.context.scene.BIMClashProperties.clash_sets[ clash_set_name = context.scene.BIMClashProperties.clash_sets[
bpy.context.scene.BIMClashProperties.active_clash_set_index context.scene.BIMClashProperties.active_clash_set_index
].name ].name
with open(smart_groups_path) as f: with open(smart_groups_path) as f:
smart_grouped_clashes = json.load(f) smart_grouped_clashes = json.load(f)
# Reset the list of smart_clash_groups for the UI # Reset the list of smart_clash_groups for the UI
bpy.context.scene.BIMClashProperties.smart_clash_groups.clear() context.scene.BIMClashProperties.smart_clash_groups.clear()
for clash_set, smart_groups in smart_grouped_clashes.items(): for clash_set, smart_groups in smart_grouped_clashes.items():
# Only select the clashes that correspond to the actively selected IFC Clash Set # Only select the clashes that correspond to the actively selected IFC Clash Set
@@ -354,7 +354,7 @@ class LoadSmartGroupsForActiveClashSet(bpy.types.Operator):
continue continue
else: else:
for smart_group, global_id_pairs in smart_groups[0].items(): for smart_group, global_id_pairs in smart_groups[0].items():
new_group = bpy.context.scene.BIMClashProperties.smart_clash_groups.add() new_group = context.scene.BIMClashProperties.smart_clash_groups.add()
new_group.number = f"{smart_group}" new_group.number = f"{smart_group}"
for pair in global_id_pairs: for pair in global_id_pairs:
for id in pair: for id in pair:
@@ -371,12 +371,12 @@ class SelectSmartGroup(bpy.types.Operator):
def execute(self, context): def execute(self, context):
# Select smart group in view # Select smart group in view
selected_smart_group = bpy.context.scene.BIMClashProperties.smart_clash_groups[ selected_smart_group = context.scene.BIMClashProperties.smart_clash_groups[
bpy.context.scene.BIMCLashProperties.active_smart_group_index context.scene.BIMCLashProperties.active_smart_group_index
] ]
# print(selected_smart_group.number) # print(selected_smart_group.number)
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
@@ -391,13 +391,13 @@ class SelectSmartGroup(bpy.types.Operator):
class BlenderClasher: class BlenderClasher:
def process_clash_set(self): def process_clash_set(self, context):
import collision import collision
a_cm = collision.CollisionManager() a_cm = collision.CollisionManager()
b_cm = collision.CollisionManager() b_cm = collision.CollisionManager()
self.add_to_cm(a_cm, bpy.context.scene.BIMClashProperties.blender_clash_set_a) self.add_to_cm(a_cm, context.scene.BIMClashProperties.blender_clash_set_a, context)
self.add_to_cm(b_cm, bpy.context.scene.BIMClashProperties.blender_clash_set_b) self.add_to_cm(b_cm, context.scene.BIMClashProperties.blender_clash_set_b, context)
results = a_cm.in_collision_other(b_cm, return_data=True) results = a_cm.in_collision_other(b_cm, return_data=True)
if not results[0]: if not results[0]:
print("No clashes") print("No clashes")
@@ -410,20 +410,20 @@ class BlenderClasher:
print(contact.raw.normal) print(contact.raw.normal)
print(contact.raw.pos) print(contact.raw.pos)
def add_to_cm(self, cm, object_names): def add_to_cm(self, cm, object_names, context):
import ifcclash import ifcclash
for object_name in object_names: for object_name in object_names:
name = object_name.name name = object_name.name
obj = bpy.data.objects[name] obj = bpy.data.objects[name]
triangulated_mesh = self.triangulate_mesh(obj) triangulated_mesh = self.triangulate_mesh(obj, context)
mesh = ifcclash.Mesh() mesh = ifcclash.Mesh()
mesh.vertices = np.array([tuple(obj.matrix_world @ v.co) for v in triangulated_mesh.vertices]) mesh.vertices = np.array([tuple(obj.matrix_world @ v.co) for v in triangulated_mesh.vertices])
mesh.faces = np.array([tuple(p.vertices) for p in triangulated_mesh.polygons]) mesh.faces = np.array([tuple(p.vertices) for p in triangulated_mesh.polygons])
cm.add_object(name, mesh) cm.add_object(name, mesh)
def triangulate_mesh(self, obj): def triangulate_mesh(self, obj, context):
mesh = obj.evaluated_get(bpy.context.evaluated_depsgraph_get()).to_mesh() mesh = obj.evaluated_get(context.evaluated_depsgraph_get()).to_mesh()
bm = bmesh.new() bm = bmesh.new()
bm.from_mesh(mesh) bm.from_mesh(mesh)
bmesh.ops.triangulate(bm, faces=bm.faces) bmesh.ops.triangulate(bm, faces=bm.faces)
@@ -439,10 +439,10 @@ class SetBlenderClashSetA(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
while len(bpy.context.scene.BIMClashProperties.blender_clash_set_a) > 0: while len(context.scene.BIMClashProperties.blender_clash_set_a) > 0:
bpy.context.scene.BIMClashProperties.blender_clash_set_a.remove(0) context.scene.BIMClashProperties.blender_clash_set_a.remove(0)
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
new = bpy.context.scene.BIMClashProperties.blender_clash_set_a.add() new = context.scene.BIMClashProperties.blender_clash_set_a.add()
new.name = obj.name new.name = obj.name
return {"FINISHED"} return {"FINISHED"}
@@ -453,10 +453,10 @@ class SetBlenderClashSetB(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
while len(bpy.context.scene.BIMClashProperties.blender_clash_set_b) > 0: while len(context.scene.BIMClashProperties.blender_clash_set_b) > 0:
bpy.context.scene.BIMClashProperties.blender_clash_set_b.remove(0) context.scene.BIMClashProperties.blender_clash_set_b.remove(0)
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
new = bpy.context.scene.BIMClashProperties.blender_clash_set_b.add() new = context.scene.BIMClashProperties.blender_clash_set_b.add()
new.name = obj.name new.name = obj.name
return {"FINISHED"} return {"FINISHED"}
@@ -467,5 +467,5 @@ class ExecuteBlenderClash(bpy.types.Operator):
def execute(self, context): def execute(self, context):
blender_clasher = BlenderClasher() blender_clasher = BlenderClasher()
blender_clasher.process_clash_set() blender_clasher.process_clash_set(context)
return {"FINISHED"} return {"FINISHED"}
@@ -133,7 +133,7 @@ class EnableEditingClassificationReference(bpy.types.Operator):
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMClassificationReferenceProperties props = obj.BIMClassificationReferenceProperties
while len(props.reference_attributes) > 0: while len(props.reference_attributes) > 0:
props.reference_attributes.remove(0) props.reference_attributes.remove(0)
@@ -157,7 +157,7 @@ class DisableEditingClassificationReference(bpy.types.Operator):
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
obj.BIMClassificationReferenceProperties.active_reference_id = 0 obj.BIMClassificationReferenceProperties.active_reference_id = 0
return {"FINISHED"} return {"FINISHED"}
@@ -173,7 +173,7 @@ class RemoveClassificationReference(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.remove_reference", "classification.remove_reference",
@@ -198,7 +198,7 @@ class EditClassificationReference(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMClassificationReferenceProperties props = obj.BIMClassificationReferenceProperties
attributes = {} attributes = {}
for attribute in props.reference_attributes: for attribute in props.reference_attributes:
@@ -228,7 +228,7 @@ class AddClassificationReference(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
classification = None classification = None
@@ -15,7 +15,7 @@ class SelectCobieIfcFile(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.COBieProperties.cobie_ifc_file = self.filepath context.scene.COBieProperties.cobie_ifc_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -30,7 +30,7 @@ class SelectCobieJsonFile(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.COBieProperties.cobie_json_file = self.filepath context.scene.COBieProperties.cobie_json_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -45,7 +45,7 @@ class ExecuteIfcCobie(bpy.types.Operator):
def execute(self, context): def execute(self, context):
from cobie import IfcCobieParser from cobie import IfcCobieParser
props = bpy.context.scene.COBieProperties props = context.scene.COBieProperties
output_dir = os.path.dirname(props.cobie_ifc_file) output_dir = os.path.dirname(props.cobie_ifc_file)
@@ -21,9 +21,9 @@ class AddSubcontext(bpy.types.Operator):
"context.add_context", "context.add_context",
self.file, self.file,
**{ **{
"context": self.context or bpy.context.scene.BIMProperties.available_contexts, "context": self.context or context.scene.BIMProperties.available_contexts,
"subcontext": self.subcontext or bpy.context.scene.BIMProperties.available_subcontexts, "subcontext": self.subcontext or context.scene.BIMProperties.available_subcontexts,
"target_view": self.target_view or bpy.context.scene.BIMProperties.available_target_views, "target_view": self.target_view or context.scene.BIMProperties.available_target_views,
}, },
) )
Data.load(IfcStore.get_file()) Data.load(IfcStore.get_file())
@@ -307,7 +307,7 @@ class AssignCostItemProduct(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects [bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
) )
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
@@ -336,7 +336,7 @@ class UnassignCostItemProduct(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects [bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
) )
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
@@ -621,7 +621,7 @@ class SelectCostItemProducts(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
related_products = Data.cost_items[self.cost_item]["Controls"] related_products = Data.cost_items[self.cost_item]["Controls"]
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
obj.select_set(False) obj.select_set(False)
if obj.BIMObjectProperties.ifc_definition_id in related_products: if obj.BIMObjectProperties.ifc_definition_id in related_products:
obj.select_set(True) obj.select_set(True)
@@ -640,7 +640,7 @@ class SelectCostScheduleProducts(bpy.types.Operator):
for cost_item_id in Data.cost_schedules[self.cost_schedule]["Controls"]: for cost_item_id in Data.cost_schedules[self.cost_schedule]["Controls"]:
self.get_related_products(Data.cost_items[cost_item_id]) self.get_related_products(Data.cost_items[cost_item_id])
self.related_products = set(self.related_products) self.related_products = set(self.related_products)
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
obj.select_set(False) obj.select_set(False)
if obj.BIMObjectProperties.ifc_definition_id in self.related_products: if obj.BIMObjectProperties.ifc_definition_id in self.related_products:
obj.select_set(True) obj.select_set(True)
@@ -16,13 +16,13 @@ class Login(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
token = api.login(bpy.context.scene.CoveToolProperties.username, bpy.context.scene.CoveToolProperties.password) token = api.login(context.scene.CoveToolProperties.username, context.scene.CoveToolProperties.password)
if token: if token:
bpy.context.scene.CoveToolProperties.token = token context.scene.CoveToolProperties.token = token
projects = api.get_request("projects") projects = api.get_request("projects")
for project in projects: for project in projects:
new_project = bpy.context.scene.CoveToolProperties.projects.add() new_project = context.scene.CoveToolProperties.projects.add()
new_project.name = project["name"] new_project.name = project["name"]
new_project.run_set = project["run_set"][0] new_project.run_set = project["run_set"][0]
new_project.url = project["url"] new_project.url = project["url"]
@@ -36,10 +36,10 @@ class RunSimpleAnalysis(bpy.types.Operator):
bl_label = "Run Simple Analysis" bl_label = "Run Simple Analysis"
def execute(self, context): def execute(self, context):
simple_analysis = bpy.context.scene.CoveToolProperties.simple_analysis simple_analysis = context.scene.CoveToolProperties.simple_analysis
data = { data = {
"run": bpy.context.scene.CoveToolProperties.projects[ "run": context.scene.CoveToolProperties.projects[
bpy.context.scene.CoveToolProperties.active_project_index context.scene.CoveToolProperties.active_project_index
].run_set, ].run_set,
"si_units": simple_analysis.si_units, "si_units": simple_analysis.si_units,
"building_height": simple_analysis.building_height, "building_height": simple_analysis.building_height,
@@ -84,10 +84,10 @@ class RunAnalysis(bpy.types.Operator):
"roofs": [], "roofs": [],
"shading_devices": [], "shading_devices": [],
} }
self.parse_objects() self.parse_objects(context)
data = { data = {
"run": bpy.context.scene.CoveToolProperties.projects[ "run": context.scene.CoveToolProperties.projects[
bpy.context.scene.CoveToolProperties.active_project_index context.scene.CoveToolProperties.active_project_index
].run_set, ].run_set,
"source": "BlenderBIM", "source": "BlenderBIM",
"rotation_angle": self.get_rotation_angle(), "rotation_angle": self.get_rotation_angle(),
@@ -112,14 +112,14 @@ class RunAnalysis(bpy.types.Operator):
rotation = 360 - rotation rotation = 360 - rotation
return rotation return rotation
def parse_objects(self): def parse_objects(self, context):
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
covetool_category = self.get_covetool_category(obj) covetool_category = self.get_covetool_category(obj)
if not covetool_category: if not covetool_category:
continue continue
if not self.has_triangulate_modifier(obj): if not self.has_triangulate_modifier(obj):
obj.modifiers.new(name="Triangulate", type="TRIANGULATE") obj.modifiers.new(name="Triangulate", type="TRIANGULATE")
mesh = obj.evaluated_get(bpy.context.evaluated_depsgraph_get()).to_mesh() mesh = obj.evaluated_get(context.evaluated_depsgraph_get()).to_mesh()
meshes = {} meshes = {}
for polygon in mesh.polygons: for polygon in mesh.polygons:
normal = "{}|{}|{}".format( normal = "{}|{}|{}".format(
@@ -29,7 +29,7 @@ class PurgeIfcLinks(bpy.types.Operator):
obj.data.BIMMeshProperties.ifc_definition_id = 0 obj.data.BIMMeshProperties.ifc_definition_id = 0
for material in bpy.data.materials: for material in bpy.data.materials:
material.BIMMaterialProperties.ifc_style_id = False material.BIMMaterialProperties.ifc_style_id = False
bpy.context.scene.BIMProperties.ifc_file = "" context.scene.BIMProperties.ifc_file = ""
IfcStore.purge() IfcStore.purge()
blenderbim.bim.handler.purge_module_data() blenderbim.bim.handler.purge_module_data()
return {"FINISHED"} return {"FINISHED"}
@@ -57,7 +57,7 @@ class ProfileImportIFC(bpy.types.Operator):
import pstats import pstats
# For Windows # For Windows
filepath = bpy.context.scene.BIMProperties.ifc_file.replace("\\", "\\\\") filepath = context.scene.BIMProperties.ifc_file.replace("\\", "\\\\")
cProfile.run(f"import bpy; bpy.ops.import_ifc.bim(filepath='{filepath}')", "blender.prof") cProfile.run(f"import bpy; bpy.ops.import_ifc.bim(filepath='{filepath}')", "blender.prof")
p = pstats.Stats("blender.prof") p = pstats.Stats("blender.prof")
@@ -102,9 +102,9 @@ class CreateShapeFromStepId(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
logger = logging.getLogger("ImportIFC") logger = logging.getLogger("ImportIFC")
self.ifc_import_settings = import_ifc.IfcImportSettings.factory(bpy.context, IfcStore.path, logger) self.ifc_import_settings = import_ifc.IfcImportSettings.factory(context, IfcStore.path, logger)
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
element = self.file.by_id(int(bpy.context.scene.BIMDebugProperties.step_id)) element = self.file.by_id(int(context.scene.BIMDebugProperties.step_id))
settings = ifcopenshell.geom.settings() settings = ifcopenshell.geom.settings()
# settings.set(settings.INCLUDE_CURVES, True) # settings.set(settings.INCLUDE_CURVES, True)
shape = ifcopenshell.geom.create_shape(settings, element) shape = ifcopenshell.geom.create_shape(settings, element)
@@ -112,7 +112,7 @@ class CreateShapeFromStepId(bpy.types.Operator):
ifc_importer.file = self.file ifc_importer.file = self.file
mesh = ifc_importer.create_mesh(element, shape) mesh = ifc_importer.create_mesh(element, shape)
obj = bpy.data.objects.new("Debug", mesh) obj = bpy.data.objects.new("Debug", mesh)
bpy.context.scene.collection.objects.link(obj) context.scene.collection.objects.link(obj)
return {"FINISHED"} return {"FINISHED"}
@@ -125,7 +125,7 @@ class SelectHighPolygonMeshes(bpy.types.Operator):
results = {} results = {}
for obj in bpy.data.objects: for obj in bpy.data.objects:
if not isinstance(obj.data, bpy.types.Mesh) or len(obj.data.polygons) < int( if not isinstance(obj.data, bpy.types.Mesh) or len(obj.data.polygons) < int(
bpy.context.scene.BIMDebugProperties.number_of_polygons context.scene.BIMDebugProperties.number_of_polygons
): ):
continue continue
try: try:
@@ -141,7 +141,7 @@ class RewindInspector(bpy.types.Operator):
bl_label = "Rewind Inspector" bl_label = "Rewind Inspector"
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BIMDebugProperties props = context.scene.BIMDebugProperties
total_breadcrumbs = len(props.step_id_breadcrumb) total_breadcrumbs = len(props.step_id_breadcrumb)
if total_breadcrumbs < 2: if total_breadcrumbs < 2:
return {"FINISHED"} return {"FINISHED"}
@@ -159,18 +159,18 @@ class InspectFromStepId(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
bpy.context.scene.BIMDebugProperties.active_step_id = self.step_id context.scene.BIMDebugProperties.active_step_id = self.step_id
crumb = bpy.context.scene.BIMDebugProperties.step_id_breadcrumb.add() crumb = context.scene.BIMDebugProperties.step_id_breadcrumb.add()
crumb.name = str(self.step_id) crumb.name = str(self.step_id)
element = self.file.by_id(self.step_id) element = self.file.by_id(self.step_id)
while len(bpy.context.scene.BIMDebugProperties.attributes) > 0: while len(context.scene.BIMDebugProperties.attributes) > 0:
bpy.context.scene.BIMDebugProperties.attributes.remove(0) context.scene.BIMDebugProperties.attributes.remove(0)
while len(bpy.context.scene.BIMDebugProperties.inverse_attributes) > 0: while len(context.scene.BIMDebugProperties.inverse_attributes) > 0:
bpy.context.scene.BIMDebugProperties.inverse_attributes.remove(0) context.scene.BIMDebugProperties.inverse_attributes.remove(0)
while len(bpy.context.scene.BIMDebugProperties.inverse_references) > 0: while len(context.scene.BIMDebugProperties.inverse_references) > 0:
bpy.context.scene.BIMDebugProperties.inverse_references.remove(0) context.scene.BIMDebugProperties.inverse_references.remove(0)
for key, value in element.get_info().items(): for key, value in element.get_info().items():
self.add_attribute(bpy.context.scene.BIMDebugProperties.attributes, key, value) self.add_attribute(context.scene.BIMDebugProperties.attributes, key, value)
for key in dir(element): for key in dir(element):
if ( if (
not key[0].isalpha() not key[0].isalpha()
@@ -179,9 +179,9 @@ class InspectFromStepId(bpy.types.Operator):
or not getattr(element, key) or not getattr(element, key)
): ):
continue continue
self.add_attribute(bpy.context.scene.BIMDebugProperties.inverse_attributes, key, getattr(element, key)) self.add_attribute(context.scene.BIMDebugProperties.inverse_attributes, key, getattr(element, key))
for inverse in self.file.get_inverse(element): for inverse in self.file.get_inverse(element):
new = bpy.context.scene.BIMDebugProperties.inverse_references.add() new = context.scene.BIMDebugProperties.inverse_references.add()
new.string_value = str(inverse) new.string_value = str(inverse)
new.int_value = inverse.id() new.int_value = inverse.id()
return {"FINISHED"} return {"FINISHED"}
@@ -205,7 +205,7 @@ class InspectFromObject(bpy.types.Operator):
bl_label = "Inspect From Object" bl_label = "Inspect From Object"
def execute(self, context): def execute(self, context):
ifc_definition_id = bpy.context.active_object.BIMObjectProperties.ifc_definition_id ifc_definition_id = context.active_object.BIMObjectProperties.ifc_definition_id
if not ifc_definition_id: if not ifc_definition_id:
return {"FINISHED"} return {"FINISHED"}
bpy.ops.bim.inspect_from_step_id(step_id=ifc_definition_id) bpy.ops.bim.inspect_from_step_id(step_id=ifc_definition_id)
@@ -49,7 +49,7 @@ class BIM_PT_debug(Panel):
row.operator("bim.rewind_inspector", icon="FRAME_PREV", text="") row.operator("bim.rewind_inspector", icon="FRAME_PREV", text="")
row.prop(props, "active_step_id", text="") row.prop(props, "active_step_id", text="")
row = layout.row(align=True) row = layout.row(align=True)
row.operator("bim.inspect_from_step_id").step_id = bpy.context.scene.BIMDebugProperties.active_step_id row.operator("bim.inspect_from_step_id").step_id = context.scene.BIMDebugProperties.active_step_id
row.operator("bim.inspect_from_object") row.operator("bim.inspect_from_object")
if props.attributes: if props.attributes:
@@ -13,7 +13,7 @@ class SelectDiffJsonFile(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.DiffProperties.diff_json_file = self.filepath context.scene.DiffProperties.diff_json_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -29,9 +29,9 @@ class VisualiseDiff(bpy.types.Operator):
def execute(self, context): def execute(self, context):
#ifc_file = IfcStore.get_file() # In case we get from Store #ifc_file = IfcStore.get_file() # In case we get from Store
ifc_file = ifcopenshell.open(context.scene.DiffProperties.diff_new_file) # for Now refer to the new file ifc_file = ifcopenshell.open(context.scene.DiffProperties.diff_new_file) # for Now refer to the new file
with open(bpy.context.scene.DiffProperties.diff_json_file, "r") as file: with open(context.scene.DiffProperties.diff_json_file, "r") as file:
diff = json.load(file) diff = json.load(file)
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
obj.color = (1.0, 1.0, 1.0, 0.2) obj.color = (1.0, 1.0, 1.0, 0.2)
global_id = ifc_file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId global_id = ifc_file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId
if not global_id: if not global_id:
@@ -42,7 +42,7 @@ class VisualiseDiff(bpy.types.Operator):
obj.color = (0.0, 1.0, 0.0, 0.2) obj.color = (0.0, 1.0, 0.0, 0.2)
elif global_id.string_value in diff["changed"]: elif global_id.string_value in diff["changed"]:
obj.color = (0.0, 0.0, 1.0, 0.2) obj.color = (0.0, 0.0, 1.0, 0.2)
area = next(area for area in bpy.context.screen.areas if area.type == "VIEW_3D") area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
area.spaces[0].shading.color_type = "OBJECT" area.spaces[0].shading.color_type = "OBJECT"
return {"FINISHED"} return {"FINISHED"}
@@ -54,7 +54,7 @@ class SelectDiffOldFile(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.DiffProperties.diff_old_file = self.filepath context.scene.DiffProperties.diff_old_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -69,7 +69,7 @@ class SelectDiffNewFile(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.DiffProperties.diff_new_file = self.filepath context.scene.DiffProperties.diff_new_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -93,12 +93,12 @@ class ExecuteIfcDiff(bpy.types.Operator):
import ifcdiff import ifcdiff
ifc_diff = ifcdiff.IfcDiff( ifc_diff = ifcdiff.IfcDiff(
bpy.context.scene.DiffProperties.diff_old_file, context.scene.DiffProperties.diff_old_file,
bpy.context.scene.DiffProperties.diff_new_file, context.scene.DiffProperties.diff_new_file,
self.filepath, self.filepath,
bpy.context.scene.DiffProperties.diff_relationships.split(), context.scene.DiffProperties.diff_relationships.split(),
) )
ifc_diff.diff() ifc_diff.diff()
ifc_diff.export() ifc_diff.export()
bpy.context.scene.DiffProperties.diff_json_file = self.filepath context.scene.DiffProperties.diff_json_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
@@ -16,13 +16,13 @@ class Annotator:
return float(sizes[str(size)]) return float(sizes[str(size)])
@staticmethod @staticmethod
def add_text(related_element=None): def add_text(context, related_element=None):
curve = bpy.data.curves.new(type="FONT", name="Text") curve = bpy.data.curves.new(type="FONT", name="Text")
curve.body = "TEXT" curve.body = "TEXT"
obj = bpy.data.objects.new("Text", curve) obj = bpy.data.objects.new("Text", curve)
obj.matrix_world = bpy.context.scene.camera.matrix_world obj.matrix_world = context.scene.camera.matrix_world
if related_element is None: if related_element is None:
location, _, _, _ = Annotator.get_placeholder_coords() location, _, _, _ = Annotator.get_placeholder_coords(context)
else: else:
obj.data.BIMTextProperties.related_element = related_element obj.data.BIMTextProperties.related_element = related_element
location = related_element.location location = related_element.location
@@ -31,12 +31,12 @@ class Annotator:
font = bpy.data.fonts.get("OpenGost TypeB TT") font = bpy.data.fonts.get("OpenGost TypeB TT")
if not font: if not font:
font = bpy.data.fonts.load( font = bpy.data.fonts.load(
os.path.join(bpy.context.scene.BIMProperties.data_dir, "fonts", "OpenGost Type B TT.ttf") os.path.join(context.scene.BIMProperties.data_dir, "fonts", "OpenGost Type B TT.ttf")
) )
font.name = "OpenGost Type B TT" font.name = "OpenGost Type B TT"
obj.data.font = font obj.data.font = font
obj.data.BIMTextProperties.font_size = "2.5" obj.data.BIMTextProperties.font_size = "2.5"
collection = bpy.context.scene.camera.users_collection[0] collection = context.scene.camera.users_collection[0]
collection.objects.link(obj) collection.objects.link(obj)
Annotator.resize_text(obj) Annotator.resize_text(obj)
return obj return obj
@@ -64,9 +64,9 @@ class Annotator:
text_obj.data.size = font_size text_obj.data.size = font_size
@staticmethod @staticmethod
def add_line_to_annotation(obj, co1=None, co2=None): def add_line_to_annotation(obj, context, co1=None, co2=None):
if co1 is None: if co1 is None:
co1, co2, _, _ = Annotator.get_placeholder_coords() co1, co2, _, _ = Annotator.get_placeholder_coords(context)
co1 = obj.matrix_world.inverted() @ co1 co1 = obj.matrix_world.inverted() @ co1
co2 = obj.matrix_world.inverted() @ co2 co2 = obj.matrix_world.inverted() @ co2
if isinstance(obj.data, bpy.types.Mesh): if isinstance(obj.data, bpy.types.Mesh):
@@ -83,8 +83,8 @@ class Annotator:
return obj return obj
@staticmethod @staticmethod
def add_plane_to_annotation(obj): def add_plane_to_annotation(obj, context):
co1, co2, co3, co4 = Annotator.get_placeholder_coords() co1, co2, co3, co4 = Annotator.get_placeholder_coords(context)
co1 = obj.matrix_world.inverted() @ co1 # bot left co1 = obj.matrix_world.inverted() @ co1 # bot left
co2 = obj.matrix_world.inverted() @ co2 # top left co2 = obj.matrix_world.inverted() @ co2 # top left
co3 = obj.matrix_world.inverted() @ co3 # bot right co3 = obj.matrix_world.inverted() @ co3 # bot right
@@ -132,8 +132,8 @@ class Annotator:
return obj return obj
@staticmethod @staticmethod
def get_annotation_obj(name, data_type): def get_annotation_obj(name, data_type, context):
collection = bpy.context.scene.camera.users_collection[0] collection = context.scene.camera.users_collection[0]
for obj in collection.objects: for obj in collection.objects:
if name in obj.name: if name in obj.name:
return obj return obj
@@ -148,13 +148,13 @@ class Annotator:
return obj return obj
@staticmethod @staticmethod
def get_placeholder_coords(): def get_placeholder_coords(context):
camera = bpy.context.scene.camera camera = context.scene.camera
z_offset = camera.matrix_world.to_quaternion() @ Vector((0, 0, -1)) z_offset = camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))
if bpy.context.scene.render.resolution_x > bpy.context.scene.render.resolution_y: if context.scene.render.resolution_x > context.scene.render.resolution_y:
y = ( y = (
camera.data.ortho_scale camera.data.ortho_scale
* (bpy.context.scene.render.resolution_y / bpy.context.scene.render.resolution_x) * (context.scene.render.resolution_y / context.scene.render.resolution_x)
/ 4 / 4
) )
else: else:
@@ -467,7 +467,7 @@ class AddAnnotation(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
if not bpy.context.scene.camera: if not context.scene.camera:
return {"FINISHED"} return {"FINISHED"}
subcontext = ifcopenshell.util.representation.get_context( subcontext = ifcopenshell.util.representation.get_context(
IfcStore.get_file(), "Plan", "Annotation", context.scene.camera.data.BIMCameraProperties.target_view IfcStore.get_file(), "Plan", "Annotation", context.scene.camera.data.BIMCameraProperties.target_view
@@ -475,17 +475,17 @@ class AddAnnotation(bpy.types.Operator):
if not subcontext: if not subcontext:
return {"FINISHED"} return {"FINISHED"}
if self.data_type == "text": if self.data_type == "text":
if bpy.context.selected_objects: if context.selected_objects:
for selected_object in bpy.context.selected_objects: for selected_object in context.selected_objects:
obj = annotation.Annotator.add_text(related_element=selected_object) obj = annotation.Annotator.add_text(context, related_element=selected_object)
else: else:
obj = annotation.Annotator.add_text() obj = annotation.Annotator.add_text(context)
else: else:
obj = annotation.Annotator.get_annotation_obj(self.obj_name, self.data_type) obj = annotation.Annotator.get_annotation_obj(self.obj_name, self.data_type, context)
if self.obj_name == "Break": if self.obj_name == "Break":
obj = annotation.Annotator.add_plane_to_annotation(obj) obj = annotation.Annotator.add_plane_to_annotation(obj, context)
else: else:
obj = annotation.Annotator.add_line_to_annotation(obj) obj = annotation.Annotator.add_line_to_annotation(obj, context)
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcAnnotation", context_id=subcontext.id()) bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcAnnotation", context_id=subcontext.id())
@@ -695,10 +695,10 @@ class GenerateReferences(bpy.types.Operator):
self.generate_grids() self.generate_grids()
if self.camera.data.BIMCameraProperties.target_view == "ELEVATION_VIEW": if self.camera.data.BIMCameraProperties.target_view == "ELEVATION_VIEW":
self.generate_grids() self.generate_grids()
self.generate_levels() self.generate_levels(context)
if self.camera.data.BIMCameraProperties.target_view == "SECTION_VIEW": if self.camera.data.BIMCameraProperties.target_view == "SECTION_VIEW":
self.generate_grids() self.generate_grids()
self.generate_levels() self.generate_levels(context)
return {"FINISHED"} return {"FINISHED"}
def filter_potential_references(self): def filter_potential_references(self):
@@ -714,7 +714,7 @@ class GenerateReferences(bpy.types.Operator):
# TODO # TODO
pass pass
def generate_levels(self): def generate_levels(self, context):
if self.camera.data.BIMCameraProperties.raster_x > self.camera.data.BIMCameraProperties.raster_y: if self.camera.data.BIMCameraProperties.raster_x > self.camera.data.BIMCameraProperties.raster_y:
width = self.camera.data.ortho_scale width = self.camera.data.ortho_scale
height = ( height = (
@@ -725,7 +725,7 @@ class GenerateReferences(bpy.types.Operator):
width = ( width = (
height / self.camera.data.BIMCameraProperties.raster_y * self.camera.data.BIMCameraProperties.raster_x height / self.camera.data.BIMCameraProperties.raster_y * self.camera.data.BIMCameraProperties.raster_x
) )
level_obj = annotation.Annotator.get_annotation_obj("Section Level", "curve") level_obj = annotation.Annotator.get_annotation_obj("Section Level", "curve", context)
width_in_mm = width * 1000 width_in_mm = width * 1000
if self.camera.data.BIMCameraProperties.diagram_scale == "CUSTOM": if self.camera.data.BIMCameraProperties.diagram_scale == "CUSTOM":
@@ -742,7 +742,7 @@ class GenerateReferences(bpy.types.Operator):
projection = self.project_point_onto_camera(obj.location) projection = self.project_point_onto_camera(obj.location)
co1 = self.camera.matrix_world @ Vector((width / 2 - (offset_percentage * width), projection[1], -1)) co1 = self.camera.matrix_world @ Vector((width / 2 - (offset_percentage * width), projection[1], -1))
co2 = self.camera.matrix_world @ Vector((-(width / 2), projection[1], -1)) co2 = self.camera.matrix_world @ Vector((-(width / 2), projection[1], -1))
annotation.Annotator.add_line_to_annotation(level_obj, co1, co2) annotation.Annotator.add_line_to_annotation(level_obj, context, co1, co2)
def project_point_onto_camera(self, point): def project_point_onto_camera(self, point):
projection = self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1)) projection = self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))
@@ -24,7 +24,7 @@ class BIM_PT_camera(Panel):
return return
layout.use_property_split = True layout.use_property_split = True
dprops = bpy.context.scene.DocProperties dprops = context.scene.DocProperties
props = context.active_object.data.BIMCameraProperties props = context.active_object.data.BIMCameraProperties
col = layout.column(align=True) col = layout.column(align=True)
@@ -92,7 +92,7 @@ class BIM_PT_drawing_underlay(Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.use_property_split = True layout.use_property_split = True
dprops = bpy.context.scene.DocProperties dprops = context.scene.DocProperties
props = context.active_object.data.BIMCameraProperties props = context.active_object.data.BIMCameraProperties
row = layout.row(align=True) row = layout.row(align=True)
@@ -142,7 +142,7 @@ class BIM_PT_drawings(Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.use_property_split = True layout.use_property_split = True
props = bpy.context.scene.DocProperties props = context.scene.DocProperties
row = layout.row(align=True) row = layout.row(align=True)
row.operator("bim.add_drawing") row.operator("bim.add_drawing")
@@ -175,7 +175,7 @@ class BIM_PT_schedules(Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.use_property_split = True layout.use_property_split = True
props = bpy.context.scene.DocProperties props = context.scene.DocProperties
row = layout.row(align=True) row = layout.row(align=True)
row.operator("bim.add_schedule") row.operator("bim.add_schedule")
@@ -200,7 +200,7 @@ class BIM_PT_sheets(Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
props = bpy.context.scene.DocProperties props = context.scene.DocProperties
row = layout.row(align=True) row = layout.row(align=True)
row.prop(props, "titleblock", text="") row.prop(props, "titleblock", text="")
@@ -315,7 +315,7 @@ class BIM_PT_annotation_utilities(Panel):
op.obj_name = "Misc" op.obj_name = "Misc"
op.data_type = "mesh" op.data_type = "mesh"
props = bpy.context.scene.DocProperties props = context.scene.DocProperties
row = layout.row(align=True) row = layout.row(align=True)
row.operator("bim.add_drawing") row.operator("bim.add_drawing")
@@ -24,10 +24,10 @@ class EditObjectPlacement(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
objs = [bpy.data.objects.get(self.obj)] if self.obj else bpy.context.selected_objects objs = [bpy.data.objects.get(self.obj)] if self.obj else context.selected_objects
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
# TODO: determine how to deal with this module dependency # TODO: determine how to deal with this module dependency
props = bpy.context.scene.BIMGeoreferenceProperties props = context.scene.BIMGeoreferenceProperties
for obj in objs: for obj in objs:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
@@ -69,7 +69,7 @@ class AddRepresentation(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
bpy.ops.bim.edit_object_placement(obj=obj.name) bpy.ops.bim.edit_object_placement(obj=obj.name)
@@ -79,7 +79,7 @@ class AddRepresentation(bpy.types.Operator):
product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
context_id = self.context_id or int(bpy.context.scene.BIMProperties.contexts) context_id = self.context_id or int(context.scene.BIMProperties.contexts)
context_of_items = self.file.by_id(context_id) context_of_items = self.file.by_id(context_id)
gprop = context.scene.BIMGeoreferenceProperties gprop = context.scene.BIMGeoreferenceProperties
@@ -164,7 +164,7 @@ class SwitchRepresentation(bpy.types.Operator):
should_switch_all_meshes: bpy.props.BoolProperty() should_switch_all_meshes: bpy.props.BoolProperty()
def execute(self, context): def execute(self, context):
self.element_obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object self.element_obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.oprops = self.element_obj.BIMObjectProperties self.oprops = self.element_obj.BIMObjectProperties
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -175,7 +175,7 @@ class SwitchRepresentation(bpy.types.Operator):
if mesh: if mesh:
self.switch_mesh(mesh) self.switch_mesh(mesh)
if not mesh or self.should_reload: if not mesh or self.should_reload:
self.pull_mesh_from_ifc() self.pull_mesh_from_ifc(context)
return {"FINISHED"} return {"FINISHED"}
def switch_mesh(self, mesh): def switch_mesh(self, mesh):
@@ -193,9 +193,9 @@ class SwitchRepresentation(bpy.types.Operator):
return self.resolve_mapped_representation(representation.Items[0].MappingSource.MappedRepresentation) return self.resolve_mapped_representation(representation.Items[0].MappingSource.MappedRepresentation)
return representation return representation
def pull_mesh_from_ifc(self): def pull_mesh_from_ifc(self, context):
logger = logging.getLogger("ImportIFC") logger = logging.getLogger("ImportIFC")
ifc_import_settings = import_ifc.IfcImportSettings.factory(bpy.context, IfcStore.path, logger) ifc_import_settings = import_ifc.IfcImportSettings.factory(context, IfcStore.path, logger)
element = self.file.by_id(self.oprops.ifc_definition_id) element = self.file.by_id(self.oprops.ifc_definition_id)
settings = ifcopenshell.geom.settings() settings = ifcopenshell.geom.settings()
@@ -247,7 +247,7 @@ class RemoveRepresentation(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
representation = self.file.by_id(self.representation_id) representation = self.file.by_id(self.representation_id)
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
is_mapped_representation = representation.RepresentationType == "MappedRepresentation" is_mapped_representation = representation.RepresentationType == "MappedRepresentation"
if is_mapped_representation: if is_mapped_representation:
mesh_name = "{}/{}".format( mesh_name = "{}/{}".format(
@@ -288,7 +288,7 @@ class UpdateRepresentation(bpy.types.Operator):
if not ContextData.is_loaded: if not ContextData.is_loaded:
ContextData.load(IfcStore.get_file()) ContextData.load(IfcStore.get_file())
objs = [bpy.data.objects.get(self.obj)] if self.obj else bpy.context.selected_objects objs = [bpy.data.objects.get(self.obj)] if self.obj else context.selected_objects
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for obj in objs: for obj in objs:
@@ -371,7 +371,7 @@ class UpdateParametricRepresentation(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
obj = bpy.context.active_object obj = context.active_object
props = obj.data.BIMMeshProperties props = obj.data.BIMMeshProperties
parameter = props.ifc_parameters[self.index] parameter = props.ifc_parameters[self.index]
element = IfcStore.get_file().by_id(parameter.step_id)[parameter.index] = parameter.value element = IfcStore.get_file().by_id(parameter.step_id)[parameter.index] = parameter.value
@@ -388,7 +388,7 @@ class GetRepresentationIfcParameters(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
obj = bpy.context.active_object obj = context.active_object
props = obj.data.BIMMeshProperties props = obj.data.BIMMeshProperties
elements = IfcStore.get_file().traverse(IfcStore.get_file().by_id(props.ifc_definition_id)) elements = IfcStore.get_file().traverse(IfcStore.get_file().by_id(props.ifc_definition_id))
for element in elements: for element in elements:
@@ -30,7 +30,7 @@ class BIM_PT_representations(Panel):
layout.label(text="No representations found") layout.label(text="No representations found")
row = layout.row(align=True) row = layout.row(align=True)
row.prop(bpy.context.scene.BIMProperties, "contexts", text="") row.prop(context.scene.BIMProperties, "contexts", text="")
row.operator("bim.add_representation", icon="ADD", text="") row.operator("bim.add_representation", icon="ADD", text="")
for ifc_definition_id in representations: for ifc_definition_id in representations:
@@ -276,7 +276,7 @@ class ConvertLocalToGlobal(bpy.types.Operator):
results = (x, y, z) results = (x, y, z)
props.coordinate_output = ",".join([str(r) for r in results]) props.coordinate_output = ",".join([str(r) for r in results])
bpy.context.scene.cursor.location = results context.scene.cursor.location = results
return {"FINISHED"} return {"FINISHED"}
@@ -322,7 +322,7 @@ class ConvertGlobalToLocal(bpy.types.Operator):
props.coordinate_output = ",".join([str(r) for r in results]) props.coordinate_output = ",".join([str(r) for r in results])
scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file()) scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file())
bpy.context.scene.cursor.location = [o * scale for o in results] context.scene.cursor.location = [o * scale for o in results]
return {"FINISHED"} return {"FINISHED"}
@@ -334,7 +334,7 @@ class GetCursorLocation(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = context.scene.BIMGeoreferenceProperties props = context.scene.BIMGeoreferenceProperties
scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file()) scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file())
project_coordinates = [o / scale for o in bpy.context.scene.cursor.location] project_coordinates = [o / scale for o in context.scene.cursor.location]
props.coordinate_input = ",".join([str(o) for o in project_coordinates]) props.coordinate_input = ",".join([str(o) for o in project_coordinates])
return {"FINISHED"} return {"FINISHED"}
@@ -347,5 +347,5 @@ class SetCursorLocation(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = context.scene.BIMGeoreferenceProperties props = context.scene.BIMGeoreferenceProperties
scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file()) scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file())
bpy.context.scene.cursor.location = [float(co) * scale for co in props.coordinate_output.split(",")] context.scene.cursor.location = [float(co) * scale for co in props.coordinate_output.split(",")]
return {"FINISHED"} return {"FINISHED"}
@@ -186,7 +186,7 @@ class SelectGroupProducts(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
obj.select_set(False) obj.select_set(False)
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
@@ -23,7 +23,7 @@ class AssignParameterizedProfile(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
profile = ifcopenshell.api.run( profile = ifcopenshell.api.run(
"profile.add_parameterized_profile", "profile.add_parameterized_profile",
@@ -51,7 +51,7 @@ class AddMaterial(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.materials.get(self.obj) if self.obj else bpy.context.active_object.active_material obj = bpy.data.materials.get(self.obj) if self.obj else context.active_object.active_material
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
result = ifcopenshell.api.run("material.add_material", self.file, **{"name": obj.name}) result = ifcopenshell.api.run("material.add_material", self.file, **{"name": obj.name})
IfcStore.link_element(result, obj) IfcStore.link_element(result, obj)
@@ -82,7 +82,7 @@ class RemoveMaterial(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.materials.get(self.obj) if self.obj else bpy.context.active_object.active_material obj = bpy.data.materials.get(self.obj) if self.obj else context.active_object.active_material
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
result = ifcopenshell.api.run( result = ifcopenshell.api.run(
"material.remove_material", "material.remove_material",
@@ -105,7 +105,7 @@ class AssignMaterial(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
material_type = self.material_type or obj.BIMObjectMaterialProperties.material_type material_type = self.material_type or obj.BIMObjectMaterialProperties.material_type
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
@@ -150,7 +150,7 @@ class UnassignMaterial(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"material.unassign_material", "material.unassign_material",
@@ -172,7 +172,7 @@ class AddConstituent(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"material.add_constituent", "material.add_constituent",
@@ -197,7 +197,7 @@ class RemoveConstituent(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"material.remove_constituent", self.file, **{"constituent": self.file.by_id(self.constituent)} "material.remove_constituent", self.file, **{"constituent": self.file.by_id(self.constituent)}
@@ -217,7 +217,7 @@ class AddProfile(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"material.add_profile", "material.add_profile",
@@ -243,7 +243,7 @@ class RemoveProfile(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run("material.remove_profile", self.file, **{"profile": self.file.by_id(self.profile)}) ifcopenshell.api.run("material.remove_profile", self.file, **{"profile": self.file.by_id(self.profile)})
Data.load_profiles() Data.load_profiles()
@@ -262,7 +262,7 @@ class AddLayer(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"material.add_layer", "material.add_layer",
@@ -289,7 +289,7 @@ class ReorderMaterialSetItem(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
material_set = self.file.by_id(self.material_set) material_set = self.file.by_id(self.material_set)
ifcopenshell.api.run( ifcopenshell.api.run(
@@ -324,7 +324,7 @@ class RemoveLayer(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run("material.remove_layer", self.file, **{"layer": self.file.by_id(self.layer)}) ifcopenshell.api.run("material.remove_layer", self.file, **{"layer": self.file.by_id(self.layer)})
Data.load_layers() Data.load_layers()
@@ -342,7 +342,7 @@ class AddListItem(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"material.add_list_item", "material.add_list_item",
@@ -368,7 +368,7 @@ class RemoveListItem(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"material.remove_list_item", "material.remove_list_item",
@@ -389,7 +389,7 @@ class EnableEditingAssignedMaterial(bpy.types.Operator):
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMObjectMaterialProperties props = obj.BIMObjectMaterialProperties
props.is_editing = True props.is_editing = True
product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id]
@@ -477,7 +477,7 @@ class DisableEditingAssignedMaterial(bpy.types.Operator):
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMObjectMaterialProperties props = obj.BIMObjectMaterialProperties
props.is_editing = False props.is_editing = False
return {"FINISHED"} return {"FINISHED"}
@@ -496,7 +496,7 @@ class EditAssignedMaterial(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMObjectMaterialProperties props = obj.BIMObjectMaterialProperties
product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id]
@@ -575,7 +575,7 @@ class EnableEditingMaterialSetItem(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.props = obj.BIMObjectMaterialProperties self.props = obj.BIMObjectMaterialProperties
self.props.active_material_set_item_id = self.material_set_item self.props.active_material_set_item_id = self.material_set_item
product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id]
@@ -667,7 +667,7 @@ class DisableEditingMaterialSetItem(bpy.types.Operator):
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMObjectMaterialProperties props = obj.BIMObjectMaterialProperties
props.active_material_set_item_id = 0 props.active_material_set_item_id = 0
return {"FINISHED"} return {"FINISHED"}
@@ -684,7 +684,7 @@ class EditMaterialSetItem(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
props = obj.BIMObjectMaterialProperties props = obj.BIMObjectMaterialProperties
product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id]
@@ -82,7 +82,7 @@ def add_object(self, context):
obj = bpy.data.objects.new("Door Profile", mesh) obj = bpy.data.objects.new("Door Profile", mesh)
context.view_layer.active_layer_collection.collection.objects.link(obj) context.view_layer.active_layer_collection.collection.objects.link(obj)
bpy.context.view_layer.objects.active = obj context.view_layer.objects.active = obj
obj.select_set(True) obj.select_set(True)
bpy.ops.object.convert(target="CURVE") bpy.ops.object.convert(target="CURVE")
@@ -100,7 +100,7 @@ def add_object(self, context):
obj2 = bpy.data.objects.new("Door", mesh) obj2 = bpy.data.objects.new("Door", mesh)
context.view_layer.active_layer_collection.collection.objects.link(obj2) context.view_layer.active_layer_collection.collection.objects.link(obj2)
bpy.context.view_layer.objects.active = obj2 context.view_layer.objects.active = obj2
obj2.select_set(True) obj2.select_set(True)
bpy.ops.object.convert(target="CURVE") bpy.ops.object.convert(target="CURVE")
@@ -130,11 +130,11 @@ def add_object(self, context):
modifier.thickness = self.overall_height - 0.045 modifier.thickness = self.overall_height - 0.045
context.view_layer.active_layer_collection.collection.objects.link(obj3) context.view_layer.active_layer_collection.collection.objects.link(obj3)
bpy.context.view_layer.objects.active = obj3 context.view_layer.objects.active = obj3
obj3.select_set(True) obj3.select_set(True)
bpy.ops.object.convert(target="MESH") bpy.ops.object.convert(target="MESH")
ctx = bpy.context.copy() ctx = context.copy()
ctx["active_object"] = obj2 ctx["active_object"] = obj2
ctx["selected_editable_objects"] = [obj2, obj3] ctx["selected_editable_objects"] = [obj2, obj3]
bpy.ops.object.join(ctx) bpy.ops.object.join(ctx)
@@ -156,7 +156,7 @@ def add_object(self, context):
modifier.thickness = self.overall_height + 0.1 modifier.thickness = self.overall_height + 0.1
context.view_layer.active_layer_collection.collection.objects.link(obj4) context.view_layer.active_layer_collection.collection.objects.link(obj4)
bpy.context.view_layer.objects.active = obj4 context.view_layer.objects.active = obj4
obj4.select_set(True) obj4.select_set(True)
bpy.ops.object.convert(target="MESH") bpy.ops.object.convert(target="MESH")
@@ -12,7 +12,7 @@ def add_object(self, context):
collection = bpy.data.collections.new(obj.name) collection = bpy.data.collections.new(obj.name)
has_site_collection = False has_site_collection = False
for child in bpy.context.view_layer.layer_collection.children: for child in context.view_layer.layer_collection.children:
if "IfcProject/" not in child.name: if "IfcProject/" not in child.name:
continue continue
for grandchild in child.children: for grandchild in child.children:
@@ -22,7 +22,7 @@ def add_object(self, context):
grandchild.collection.children.link(collection) grandchild.collection.children.link(collection)
break break
if not has_site_collection: if not has_site_collection:
bpy.context.view_layer.active_layer_collection.collection.children.link(collection) context.view_layer.active_layer_collection.collection.children.link(collection)
collection.objects.link(obj) collection.objects.link(obj)
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -64,7 +64,7 @@ class AddTypeInstance(bpy.types.Operator):
mesh.from_pydata(verts, edges, faces) mesh.from_pydata(verts, edges, faces)
obj = bpy.data.objects.new("Instance", mesh) obj = bpy.data.objects.new("Instance", mesh)
obj.location = context.scene.cursor.location obj.location = context.scene.cursor.location
collection = bpy.context.view_layer.active_layer_collection.collection collection = context.view_layer.active_layer_collection.collection
collection.objects.link(obj) collection.objects.link(obj)
collection_obj = bpy.data.objects.get(collection.name) collection_obj = bpy.data.objects.get(collection.name)
bpy.ops.bim.assign_class(obj=obj.name, ifc_class=instance_class) bpy.ops.bim.assign_class(obj=obj.name, ifc_class=instance_class)
@@ -97,8 +97,8 @@ class AlignProduct(bpy.types.Operator):
active_y_axis = context.active_object.matrix_world.to_quaternion() @ Vector((0, 1, 0)) active_y_axis = context.active_object.matrix_world.to_quaternion() @ Vector((0, 1, 0))
active_z_axis = context.active_object.matrix_world.to_quaternion() @ Vector((0, 0, 1)) active_z_axis = context.active_object.matrix_world.to_quaternion() @ Vector((0, 0, 1))
x_distances = self.get_axis_distances(point, active_x_axis) x_distances = self.get_axis_distances(point, active_x_axis, context)
y_distances = self.get_axis_distances(point, active_y_axis) y_distances = self.get_axis_distances(point, active_y_axis, context)
if abs(sum(x_distances)) < abs(sum(y_distances)): if abs(sum(x_distances)) < abs(sum(y_distances)):
for i, obj in enumerate(selected_objs): for i, obj in enumerate(selected_objs):
obj.matrix_world = Matrix.Translation(active_x_axis * -x_distances[i]) @ obj.matrix_world obj.matrix_world = Matrix.Translation(active_x_axis * -x_distances[i]) @ obj.matrix_world
@@ -107,9 +107,9 @@ class AlignProduct(bpy.types.Operator):
obj.matrix_world = Matrix.Translation(active_y_axis * -y_distances[i]) @ obj.matrix_world obj.matrix_world = Matrix.Translation(active_y_axis * -y_distances[i]) @ obj.matrix_world
return {"FINISHED"} return {"FINISHED"}
def get_axis_distances(self, point, axis): def get_axis_distances(self, point, axis, context):
results = [] results = []
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if self.align_type == "CENTERLINE": if self.align_type == "CENTERLINE":
obj_point = obj.matrix_world @ (Vector(obj.bound_box[0]) + (obj.dimensions / 2)) obj_point = obj.matrix_world @ (Vector(obj.bound_box[0]) + (obj.dimensions / 2))
elif self.align_type == "POSITIVE": elif self.align_type == "POSITIVE":
@@ -218,7 +218,7 @@ class AddSlabOpening(bpy.types.Operator):
if not raycast[0]: if not raycast[0]:
return {"FINISHED"} return {"FINISHED"}
bpy.ops.mesh.primitive_cube_add(size=slab_obj.dimensions[2] * 2) bpy.ops.mesh.primitive_cube_add(size=slab_obj.dimensions[2] * 2)
opening = bpy.context.selected_objects[0] opening = context.selected_objects[0]
# Place the opening in the middle of the slab # Place the opening in the middle of the slab
global_location = slab_obj.matrix_world @ raycast[1] global_location = slab_obj.matrix_world @ raycast[1]
@@ -67,7 +67,7 @@ def add_object(self, context):
obj = bpy.data.objects.new("Window Profile", mesh) obj = bpy.data.objects.new("Window Profile", mesh)
context.view_layer.active_layer_collection.collection.objects.link(obj) context.view_layer.active_layer_collection.collection.objects.link(obj)
bpy.context.view_layer.objects.active = obj context.view_layer.objects.active = obj
obj.select_set(True) obj.select_set(True)
bpy.ops.object.convert(target="CURVE") bpy.ops.object.convert(target="CURVE")
@@ -85,7 +85,7 @@ def add_object(self, context):
obj2 = bpy.data.objects.new("Window", mesh) obj2 = bpy.data.objects.new("Window", mesh)
context.view_layer.active_layer_collection.collection.objects.link(obj2) context.view_layer.active_layer_collection.collection.objects.link(obj2)
bpy.context.view_layer.objects.active = obj2 context.view_layer.objects.active = obj2
obj2.select_set(True) obj2.select_set(True)
bpy.ops.object.convert(target="CURVE") bpy.ops.object.convert(target="CURVE")
obj2.data.splines[0].use_cyclic_u = True obj2.data.splines[0].use_cyclic_u = True
@@ -116,11 +116,11 @@ def add_object(self, context):
modifier.thickness = self.overall_height - 0.08 modifier.thickness = self.overall_height - 0.08
context.view_layer.active_layer_collection.collection.objects.link(obj3) context.view_layer.active_layer_collection.collection.objects.link(obj3)
bpy.context.view_layer.objects.active = obj3 context.view_layer.objects.active = obj3
obj3.select_set(True) obj3.select_set(True)
bpy.ops.object.convert(target="MESH") bpy.ops.object.convert(target="MESH")
ctx = bpy.context.copy() ctx = context.copy()
ctx["active_object"] = obj2 ctx["active_object"] = obj2
ctx["selected_editable_objects"] = [obj2, obj3] ctx["selected_editable_objects"] = [obj2, obj3]
bpy.ops.object.join(ctx) bpy.ops.object.join(ctx)
@@ -142,7 +142,7 @@ def add_object(self, context):
modifier.thickness = self.overall_height modifier.thickness = self.overall_height
context.view_layer.active_layer_collection.collection.objects.link(obj4) context.view_layer.active_layer_collection.collection.objects.link(obj4)
bpy.context.view_layer.objects.active = obj4 context.view_layer.objects.active = obj4
obj4.select_set(True) obj4.select_set(True)
bpy.ops.object.convert(target="MESH") bpy.ops.object.convert(target="MESH")
obj4.display_type = "WIRE" obj4.display_type = "WIRE"
@@ -4,8 +4,8 @@ from ifcopenshell.api.owner.data import Data
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
def draw_roles_ui(box, assigned_object_id, roles): def draw_roles_ui(box, assigned_object_id, roles, context):
props = bpy.context.scene.BIMOwnerProperties props = context.scene.BIMOwnerProperties
row = box.row(align=True) row = box.row(align=True)
row.label(text="Roles") row.label(text="Roles")
row.operator("bim.add_role", icon="ADD", text="").assigned_object_id = assigned_object_id row.operator("bim.add_role", icon="ADD", text="").assigned_object_id = assigned_object_id
@@ -30,8 +30,8 @@ def draw_roles_ui(box, assigned_object_id, roles):
row.operator("bim.remove_role", icon="X", text="").role_id = role_id row.operator("bim.remove_role", icon="X", text="").role_id = role_id
def draw_addresses_ui(box, assigned_object_id, addresses, file): def draw_addresses_ui(box, assigned_object_id, addresses, file, context):
props = bpy.context.scene.BIMOwnerProperties props = context.scene.BIMOwnerProperties
row = box.row(align=True) row = box.row(align=True)
row.label(text="Addresses") row.label(text="Addresses")
op = row.operator("bim.add_address", icon="LINK_BLEND", text="") op = row.operator("bim.add_address", icon="LINK_BLEND", text="")
@@ -135,8 +135,8 @@ class BIM_PT_people(Panel):
row = box.row() row = box.row()
row.prop(blender_person, "suffix_titles") row.prop(blender_person, "suffix_titles")
draw_roles_ui(box, person_id, person["Roles"]) draw_roles_ui(box, person_id, person["Roles"], context)
draw_addresses_ui(box, person_id, person["Addresses"], self.file) draw_addresses_ui(box, person_id, person["Addresses"], self.file, context)
else: else:
row = self.layout.row(align=True) row = self.layout.row(align=True)
name = person["Id"] if self.file.schema == "IFC2X3" else person["Identification"] name = person["Id"] if self.file.schema == "IFC2X3" else person["Identification"]
@@ -189,8 +189,8 @@ class BIM_PT_organisations(Panel):
row = box.row() row = box.row()
row.prop(blender_organisation, "description") row.prop(blender_organisation, "description")
draw_roles_ui(box, organisation_id, organisation["Roles"]) draw_roles_ui(box, organisation_id, organisation["Roles"], context)
draw_addresses_ui(box, organisation_id, organisation["Addresses"], self.file) draw_addresses_ui(box, organisation_id, organisation["Addresses"], self.file, context)
else: else:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text=organisation["Name"]) row.label(text=organisation["Name"])
@@ -29,7 +29,7 @@ class CreateProject(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
IfcStore.file = ifcopenshell.api.run( IfcStore.file = ifcopenshell.api.run(
"project.create_file", **{"version": bpy.context.scene.BIMProperties.export_schema} "project.create_file", **{"version": context.scene.BIMProperties.export_schema}
) )
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -49,7 +49,7 @@ class CreateProject(bpy.types.Operator):
bpy.ops.bim.add_subcontext(context="Plan") bpy.ops.bim.add_subcontext(context="Plan")
bpy.ops.bim.add_subcontext(context="Plan", subcontext="Annotation", target_view="PLAN_VIEW") bpy.ops.bim.add_subcontext(context="Plan", subcontext="Annotation", target_view="PLAN_VIEW")
bpy.context.scene.BIMProperties.contexts = str( context.scene.BIMProperties.contexts = str(
ifcopenshell.util.representation.get_context(self.file, "Model", "Body", "MODEL_VIEW").id() ifcopenshell.util.representation.get_context(self.file, "Model", "Body", "MODEL_VIEW").id()
) )
@@ -97,7 +97,7 @@ class CreateProjectLibrary(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
IfcStore.file = ifcopenshell.api.run( IfcStore.file = ifcopenshell.api.run(
"project.create_file", **{"version": bpy.context.scene.BIMProperties.export_schema} "project.create_file", **{"version": context.scene.BIMProperties.export_schema}
) )
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -326,14 +326,14 @@ class AppendLibraryElement(bpy.types.Operator):
library=IfcStore.library_file, library=IfcStore.library_file,
element=IfcStore.library_file.by_id(self.definition), element=IfcStore.library_file.by_id(self.definition),
) )
self.import_type_from_ifc(element) self.import_type_from_ifc(element, context)
blenderbim.bim.handler.purge_module_data() blenderbim.bim.handler.purge_module_data()
return {"FINISHED"} return {"FINISHED"}
def import_type_from_ifc(self, element): def import_type_from_ifc(self, element, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
logger = logging.getLogger("ImportIFC") logger = logging.getLogger("ImportIFC")
ifc_import_settings = import_ifc.IfcImportSettings.factory(bpy.context, IfcStore.path, logger) ifc_import_settings = import_ifc.IfcImportSettings.factory(context, IfcStore.path, logger)
type_collection = bpy.data.collections.get("Types") type_collection = bpy.data.collections.get("Types")
if not type_collection: if not type_collection:
@@ -16,7 +16,7 @@ class TogglePsetExpansion(bpy.types.Operator):
pset_id: bpy.props.IntProperty() pset_id: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
obj = bpy.context.active_object obj = context.active_object
data = Data.psets if self.pset_id in Data.psets else Data.qtos data = Data.psets if self.pset_id in Data.psets else Data.qtos
data[self.pset_id]["is_expanded"] = not data[self.pset_id]["is_expanded"] data[self.pset_id]["is_expanded"] = not data[self.pset_id]["is_expanded"]
return {"FINISHED"} return {"FINISHED"}
@@ -295,7 +295,7 @@ class AddQto(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
obj = bpy.context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.PsetProperties props = obj.PsetProperties
ifcopenshell.api.run( ifcopenshell.api.run(
@@ -318,23 +318,23 @@ class GuessQuantity(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.qto_calculator = QtoCalculator() self.qto_calculator = QtoCalculator()
obj = bpy.context.active_object obj = context.active_object
prop = obj.PsetProperties.properties.get(self.prop) prop = obj.PsetProperties.properties.get(self.prop)
prop.float_value = self.guess_quantity(obj) prop.float_value = self.guess_quantity(obj, context)
return {"FINISHED"} return {"FINISHED"}
def guess_quantity(self, obj): def guess_quantity(self, obj, context):
quantity = self.qto_calculator.guess_quantity(self.prop, [p.name for p in obj.PsetProperties.properties], obj) quantity = self.qto_calculator.guess_quantity(self.prop, [p.name for p in obj.PsetProperties.properties], obj)
if "area" in self.prop.lower(): if "area" in self.prop.lower():
if bpy.context.scene.BIMProperties.area_unit: if context.scene.BIMProperties.area_unit:
prefix, name = self.get_prefix_name(bpy.context.scene.BIMProperties.area_unit) prefix, name = self.get_prefix_name(context.scene.BIMProperties.area_unit)
quantity = ifcopenshell.util.unit.convert(quantity, None, "SQUARE_METRE", prefix, name) quantity = ifcopenshell.util.unit.convert(quantity, None, "SQUARE_METRE", prefix, name)
elif "volume" in self.prop.lower(): elif "volume" in self.prop.lower():
if bpy.context.scene.BIMProperties.volume_unit: if context.scene.BIMProperties.volume_unit:
prefix, name = self.get_prefix_name(bpy.context.scene.BIMProperties.volume_unit) prefix, name = self.get_prefix_name(context.scene.BIMProperties.volume_unit)
quantity = ifcopenshell.util.unit.convert(quantity, None, "CUBIC_METRE", prefix, name) quantity = ifcopenshell.util.unit.convert(quantity, None, "CUBIC_METRE", prefix, name)
else: else:
prefix, name = self.get_blender_prefix_name() prefix, name = self.get_blender_prefix_name(context)
quantity = ifcopenshell.util.unit.convert(quantity, None, "METRE", prefix, name) quantity = ifcopenshell.util.unit.convert(quantity, None, "METRE", prefix, name)
return round(quantity, 3) return round(quantity, 3)
@@ -343,13 +343,14 @@ class GuessQuantity(bpy.types.Operator):
return value.split("/") return value.split("/")
return None, value return None, value
def get_blender_prefix_name(self): def get_blender_prefix_name(self, context):
if bpy.context.scene.unit_settings.system == "IMPERIAL": unit_settings = context.scene.unit_settings
if bpy.context.scene.unit_settings.length_unit == "INCHES": if unit_settings.system == "IMPERIAL":
if unit_settings.length_unit == "INCHES":
return None, "inch" return None, "inch"
elif bpy.context.scene.unit_settings.length_unit == "FEET": elif unit_settings.length_unit == "FEET":
return None, "foot" return None, "foot"
elif bpy.context.scene.unit_settings.system == "METRIC": elif unit_settings.system == "METRIC":
if bpy.context.scene.unit_settings.length_unit == "METERS": if unit_settings.length_unit == "METERS":
return None, "METRE" return None, "METRE"
return bpy.context.scene.unit_settings.length_unit[0 : -len("METERS")], "METRE" return unit_settings.length_unit[0 : -len("METERS")], "METRE"
@@ -14,7 +14,7 @@ def calculate_volume(obj):
return result return result
def calculate_formwork_area(objs): def calculate_formwork_area(objs, context):
""" """
Formwork is defined as the surface area required to cover all exposed Formwork is defined as the surface area required to cover all exposed
surfaces of one or more objects, excluding top surfaces (i.e. that have a surfaces of one or more objects, excluding top surfaces (i.e. that have a
@@ -27,7 +27,7 @@ def calculate_formwork_area(objs):
new_obj = obj.copy() new_obj = obj.copy()
new_obj.data = obj.data.copy() new_obj.data = obj.data.copy()
new_obj.animation_data_clear() new_obj.animation_data_clear()
bpy.context.collection.objects.link(new_obj) context.collection.objects.link(new_obj)
copied_objs.append(new_obj) copied_objs.append(new_obj)
context_override = {} context_override = {}
@@ -53,7 +53,7 @@ def calculate_formwork_area(objs):
else: else:
modifier.octree_depth = 5 modifier.octree_depth = 5
mesh = copied_objs[0].evaluated_get(bpy.context.evaluated_depsgraph_get()).to_mesh() mesh = copied_objs[0].evaluated_get(context.evaluated_depsgraph_get()).to_mesh()
for polygon in mesh.polygons: for polygon in mesh.polygons:
if polygon.normal.z > 0.5: if polygon.normal.z > 0.5:
continue continue
@@ -14,13 +14,13 @@ class CalculateEdgeLengths(bpy.types.Operator):
def execute(self, context): def execute(self, context):
result = 0 result = 0
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if not obj.data or not obj.data.edges: if not obj.data or not obj.data.edges:
continue continue
for edge in obj.data.edges: for edge in obj.data.edges:
if edge.select: if edge.select:
result += (obj.data.vertices[edge.vertices[1]].co - obj.data.vertices[edge.vertices[0]].co).length result += (obj.data.vertices[edge.vertices[1]].co - obj.data.vertices[edge.vertices[0]].co).length
bpy.context.scene.BIMQtoProperties.qto_result = str(round(result, 3)) context.scene.BIMQtoProperties.qto_result = str(round(result, 3))
return {"FINISHED"} return {"FINISHED"}
@@ -31,13 +31,13 @@ class CalculateFaceAreas(bpy.types.Operator):
def execute(self, context): def execute(self, context):
result = 0 result = 0
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if not obj.data or not obj.data.polygons: if not obj.data or not obj.data.polygons:
continue continue
for polygon in obj.data.polygons: for polygon in obj.data.polygons:
if polygon.select: if polygon.select:
result += polygon.area result += polygon.area
bpy.context.scene.BIMQtoProperties.qto_result = str(round(result, 3)) context.scene.BIMQtoProperties.qto_result = str(round(result, 3))
return {"FINISHED"} return {"FINISHED"}
@@ -48,14 +48,14 @@ class CalculateObjectVolumes(bpy.types.Operator):
def execute(self, context): def execute(self, context):
result = 0 result = 0
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if not obj.data or not isinstance(obj.data, bpy.types.Mesh): if not obj.data or not isinstance(obj.data, bpy.types.Mesh):
continue continue
bm = bmesh.new() bm = bmesh.new()
bm.from_mesh(obj.data) bm.from_mesh(obj.data)
result += bm.calc_volume() result += bm.calc_volume()
bm.free() bm.free()
bpy.context.scene.BIMQtoProperties.qto_result = str(round(result, 3)) context.scene.BIMQtoProperties.qto_result = str(round(result, 3))
return {"FINISHED"} return {"FINISHED"}
@@ -65,16 +65,16 @@ class ExecuteQtoMethod(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BIMQtoProperties props = context.scene.BIMQtoProperties
result = 0 result = 0
if props.qto_methods == "HEIGHT": if props.qto_methods == "HEIGHT":
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
result += helper.calculate_height(obj) result += helper.calculate_height(obj)
elif props.qto_methods == "VOLUME": elif props.qto_methods == "VOLUME":
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
result += helper.calculate_volume(obj) result += helper.calculate_volume(obj)
elif props.qto_methods == "FORMWORK": elif props.qto_methods == "FORMWORK":
result = helper.calculate_formwork_area(bpy.context.selected_objects) result = helper.calculate_formwork_area(context.selected_objects, context)
props.qto_result = str(round(result, 3)) props.qto_result = str(round(result, 3))
return {"FINISHED"} return {"FINISHED"}
@@ -88,9 +88,9 @@ class QuantifyObjects(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
props = bpy.context.scene.BIMQtoProperties props = context.scene.BIMQtoProperties
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
result = 0 result = 0
@@ -99,7 +99,7 @@ class QuantifyObjects(bpy.types.Operator):
elif props.qto_methods == "VOLUME": elif props.qto_methods == "VOLUME":
result = helper.calculate_volume(obj) result = helper.calculate_volume(obj)
elif props.qto_methods == "FORMWORK": elif props.qto_methods == "FORMWORK":
result = helper.calculate_formwork_area([obj]) result = helper.calculate_formwork_area([obj], context)
if not result: if not result:
continue continue
result = round(result, 3) result = round(result, 3)
@@ -230,7 +230,7 @@ class AssignResource(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects [bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
) )
for related_object in related_objects: for related_object in related_objects:
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -253,7 +253,7 @@ class UnassignResource(bpy.types.Operator):
def execute(self, context): def execute(self, context):
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects [bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
) )
for related_object in related_objects: for related_object in related_objects:
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -15,10 +15,10 @@ class EnableReassignClass(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
obj = bpy.context.active_object obj = context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifc_class = obj.name.split("/")[0] ifc_class = obj.name.split("/")[0]
bpy.context.active_object.BIMObjectProperties.is_reassigning_class = True context.active_object.BIMObjectProperties.is_reassigning_class = True
ifc_products = [ ifc_products = [
"IfcElement", "IfcElement",
"IfcElementType", "IfcElementType",
@@ -31,11 +31,11 @@ class EnableReassignClass(bpy.types.Operator):
] ]
for ifc_product in ifc_products: for ifc_product in ifc_products:
if ifcopenshell.util.schema.is_a(IfcStore.get_schema().declaration_by_name(ifc_class), ifc_product): if ifcopenshell.util.schema.is_a(IfcStore.get_schema().declaration_by_name(ifc_class), ifc_product):
bpy.context.scene.BIMRootProperties.ifc_product = ifc_product context.scene.BIMRootProperties.ifc_product = ifc_product
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
bpy.context.scene.BIMRootProperties.ifc_class = element.is_a() context.scene.BIMRootProperties.ifc_class = element.is_a()
if hasattr(element, "PredefinedType") and element.PredefinedType: if hasattr(element, "PredefinedType") and element.PredefinedType:
bpy.context.scene.BIMRootProperties.ifc_predefined_type = element.PredefinedType context.scene.BIMRootProperties.ifc_predefined_type = element.PredefinedType
return {"FINISHED"} return {"FINISHED"}
@@ -45,7 +45,7 @@ class DisableReassignClass(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
bpy.context.active_object.BIMObjectProperties.is_reassigning_class = False context.active_object.BIMObjectProperties.is_reassigning_class = False
return {"FINISHED"} return {"FINISHED"}
@@ -59,18 +59,18 @@ class ReassignClass(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
objects = [bpy.data.objects.get(self.obj)] if self.obj else bpy.context.selected_objects objects = [bpy.data.objects.get(self.obj)] if self.obj else context.selected_objects
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
predefined_type = bpy.context.scene.BIMRootProperties.ifc_predefined_type predefined_type = context.scene.BIMRootProperties.ifc_predefined_type
if predefined_type == "USERDEFINED": if predefined_type == "USERDEFINED":
predefined_type = bpy.context.scene.BIMRootProperties.ifc_userdefined_type predefined_type = context.scene.BIMRootProperties.ifc_userdefined_type
for obj in objects: for obj in objects:
product = ifcopenshell.api.run( product = ifcopenshell.api.run(
"root.reassign_class", "root.reassign_class",
self.file, self.file,
**{ **{
"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id), "product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
"ifc_class": bpy.context.scene.BIMRootProperties.ifc_class, "ifc_class": context.scene.BIMRootProperties.ifc_class,
"predefined_type": predefined_type, "predefined_type": predefined_type,
}, },
) )
@@ -96,7 +96,7 @@ class AssignClass(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
objects = [bpy.data.objects.get(self.obj)] if self.obj else bpy.context.selected_objects objects = [bpy.data.objects.get(self.obj)] if self.obj else context.selected_objects
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
self.declaration = IfcStore.get_schema().declaration_by_name(self.ifc_class) self.declaration = IfcStore.get_schema().declaration_by_name(self.ifc_class)
if self.predefined_type == "USERDEFINED": if self.predefined_type == "USERDEFINED":
@@ -128,22 +128,22 @@ class AssignClass(bpy.types.Operator):
) )
if product.is_a("IfcElementType"): if product.is_a("IfcElementType"):
self.place_in_types_collection(obj) self.place_in_types_collection(obj, context)
elif product.is_a("IfcOpeningElement"): elif product.is_a("IfcOpeningElement"):
self.place_in_openings_collection(obj) self.place_in_openings_collection(obj, context)
elif ( elif (
product.is_a("IfcSpatialElement") product.is_a("IfcSpatialElement")
or product.is_a("IfcSpatialStructureElement") or product.is_a("IfcSpatialStructureElement")
or product.is_a("IfcProject") or product.is_a("IfcProject")
or product.is_a("IfcContext") or product.is_a("IfcContext")
): ):
self.place_in_spatial_collection(obj) self.place_in_spatial_collection(obj, context)
else: else:
self.assign_potential_spatial_container(obj) self.assign_potential_spatial_container(obj)
context.view_layer.objects.active = obj context.view_layer.objects.active = obj
def place_in_types_collection(self, obj): def place_in_types_collection(self, obj, context):
for project in [c for c in bpy.context.view_layer.layer_collection.children if "IfcProject" in c.name]: for project in [c for c in context.view_layer.layer_collection.children if "IfcProject" in c.name]:
if not [c for c in project.children if "Types" in c.name]: if not [c for c in project.children if "Types" in c.name]:
types = bpy.data.collections.new("Types") types = bpy.data.collections.new("Types")
project.collection.children.link(types) project.collection.children.link(types)
@@ -154,8 +154,8 @@ class AssignClass(bpy.types.Operator):
break break
break break
def place_in_openings_collection(self, obj): def place_in_openings_collection(self, obj, context):
for project in [c for c in bpy.context.view_layer.layer_collection.children if "IfcProject" in c.name]: for project in [c for c in context.view_layer.layer_collection.children if "IfcProject" in c.name]:
if not [c for c in project.children if "IfcOpeningElements" in c.name]: if not [c for c in project.children if "IfcOpeningElements" in c.name]:
opening_elements = bpy.data.collections.new("IfcOpeningElements") opening_elements = bpy.data.collections.new("IfcOpeningElements")
project.collection.children.link(opening_elements) project.collection.children.link(opening_elements)
@@ -166,7 +166,7 @@ class AssignClass(bpy.types.Operator):
break break
break break
def place_in_spatial_collection(self, obj): def place_in_spatial_collection(self, obj, context):
for collection in obj.users_collection: for collection in obj.users_collection:
if collection.name == obj.name: if collection.name == obj.name:
return return
@@ -181,7 +181,7 @@ class AssignClass(bpy.types.Operator):
parent_collection.children.link(collection) parent_collection.children.link(collection)
bpy.ops.bim.assign_object(related_object=obj.name, relating_object=parent_collection.name) bpy.ops.bim.assign_object(related_object=obj.name, relating_object=parent_collection.name)
else: else:
bpy.context.scene.collection.children.link(collection) context.scene.collection.children.link(collection)
def assign_potential_spatial_container(self, obj): def assign_potential_spatial_container(self, obj):
for collection in obj.users_collection: for collection in obj.users_collection:
@@ -209,7 +209,7 @@ class UnassignClass(bpy.types.Operator):
if self.obj: if self.obj:
objects = [bpy.data.objects.get(self.obj)] objects = [bpy.data.objects.get(self.obj)]
else: else:
objects = bpy.context.selected_objects objects = context.selected_objects
for obj in objects: for obj in objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
@@ -252,7 +252,7 @@ class UnlinkObject(bpy.types.Operator):
if self.obj: if self.obj:
objects = [bpy.data.objects.get(self.obj)] objects = [bpy.data.objects.get(self.obj)]
else: else:
objects = bpy.context.selected_objects objects = context.selected_objects
for obj in objects: for obj in objects:
if obj.BIMObjectProperties.ifc_definition_id: if obj.BIMObjectProperties.ifc_definition_id:
IfcStore.unlink_element(obj=obj) IfcStore.unlink_element(obj=obj)
@@ -275,7 +275,7 @@ class CopyClass(bpy.types.Operator):
if self.obj: if self.obj:
objects = [bpy.data.objects.get(self.obj)] objects = [bpy.data.objects.get(self.obj)]
else: else:
objects = bpy.context.selected_objects objects = context.selected_objects
for obj in objects: for obj in objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
@@ -30,7 +30,7 @@ class BIM_PT_class(Panel):
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.operator("bim.reassign_class", icon="CHECKMARK") row.operator("bim.reassign_class", icon="CHECKMARK")
row.operator("bim.disable_reassign_class", icon="X", text="") row.operator("bim.disable_reassign_class", icon="X", text="")
self.draw_class_dropdowns() self.draw_class_dropdowns(context)
else: else:
data = Data.products[props.ifc_definition_id] data = Data.products[props.ifc_definition_id]
name = data["type"] name = data["type"]
@@ -50,15 +50,15 @@ class BIM_PT_class(Panel):
else: else:
row.operator("bim.unassign_class", icon="X", text="").obj = context.active_object.name row.operator("bim.unassign_class", icon="X", text="").obj = context.active_object.name
else: else:
self.draw_class_dropdowns() self.draw_class_dropdowns(context)
row = self.layout.row(align=True) row = self.layout.row(align=True)
op = row.operator("bim.assign_class") op = row.operator("bim.assign_class")
op.ifc_class = bpy.context.scene.BIMRootProperties.ifc_class op.ifc_class = context.scene.BIMRootProperties.ifc_class
op.predefined_type = bpy.context.scene.BIMRootProperties.ifc_predefined_type op.predefined_type = context.scene.BIMRootProperties.ifc_predefined_type
op.userdefined_type = bpy.context.scene.BIMRootProperties.ifc_userdefined_type op.userdefined_type = context.scene.BIMRootProperties.ifc_userdefined_type
def draw_class_dropdowns(self): def draw_class_dropdowns(self, context):
props = bpy.context.scene.BIMRootProperties props = context.scene.BIMRootProperties
row = self.layout.row() row = self.layout.row()
row.prop(props, "ifc_product") row.prop(props, "ifc_product")
row = self.layout.row() row = self.layout.row()
@@ -70,4 +70,4 @@ class BIM_PT_class(Panel):
row = self.layout.row() row = self.layout.row()
row.prop(props, "ifc_userdefined_type") row.prop(props, "ifc_userdefined_type")
row = self.layout.row() row = self.layout.row()
row.prop(bpy.context.scene.BIMProperties, "contexts") row.prop(context.scene.BIMProperties, "contexts")
@@ -22,17 +22,18 @@ colour_list = [
] ]
def does_keyword_exist(pattern, string): def does_keyword_exist(pattern, string, context):
string = str(string) string = str(string)
props = context.scene.BIMSearchProperties
if ( if (
bpy.context.scene.BIMSearchProperties.should_use_regex props.should_use_regex
and bpy.context.scene.BIMSearchProperties.should_ignorecase and props.should_ignorecase
and re.search(pattern, string, flags=re.IGNORECASE) and re.search(pattern, string, flags=re.IGNORECASE)
): ):
return True return True
elif bpy.context.scene.BIMSearchProperties.should_use_regex and re.search(pattern, string): elif props.should_use_regex and re.search(pattern, string):
return True return True
elif bpy.context.scene.BIMSearchProperties.should_ignorecase and string.lower() == pattern.lower(): elif props.should_ignorecase and string.lower() == pattern.lower():
return True return True
elif string == pattern: elif string == pattern:
return True return True
@@ -70,7 +71,7 @@ class SelectIfcClass(bpy.types.Operator):
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
if does_keyword_exist(self.ifc_class, element.is_a()): if does_keyword_exist(self.ifc_class, element.is_a(), context):
obj.select_set(True) obj.select_set(True)
return {"FINISHED"} return {"FINISHED"}
@@ -94,7 +95,7 @@ class SelectAttribute(bpy.types.Operator):
value = next((v for k, v in data.items() if k.lower() == attribute_name.lower()), None) value = next((v for k, v in data.items() if k.lower() == attribute_name.lower()), None)
else: else:
value = getattr(element, attribute_name, None) value = getattr(element, attribute_name, None)
if does_keyword_exist(pattern, value): if does_keyword_exist(pattern, value, context):
obj.select_set(True) obj.select_set(True)
return {"FINISHED"} return {"FINISHED"}
@@ -126,7 +127,7 @@ class SelectPset(bpy.types.Operator):
else: else:
props = props or psets.get(search_pset_name, {}) props = props or psets.get(search_pset_name, {})
value = props.get(search_prop_name, None) value = props.get(search_prop_name, None)
if does_keyword_exist(pattern, value): if does_keyword_exist(pattern, value, context):
obj.select_set(True) obj.select_set(True)
return {"FINISHED"} return {"FINISHED"}
@@ -138,7 +139,7 @@ class ColourByAttribute(bpy.types.Operator):
def execute(self, context): def execute(self, context):
IfcStore.begin_transaction(self) IfcStore.begin_transaction(self)
self.store_state() self.store_state(context)
result = self._execute(context) result = self._execute(context)
IfcStore.add_transaction_operation(self) IfcStore.add_transaction_operation(self)
IfcStore.end_transaction(self) IfcStore.end_transaction(self)
@@ -161,13 +162,13 @@ class ColourByAttribute(bpy.types.Operator):
if value not in values: if value not in values:
values[value] = next(colours) values[value] = next(colours)
obj.color = values[value] obj.color = values[value]
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"] areas = [a for a in context.screen.areas if a.type == "VIEW_3D"]
if areas: if areas:
areas[0].spaces[0].shading.color_type = "OBJECT" areas[0].spaces[0].shading.color_type = "OBJECT"
return {"FINISHED"} return {"FINISHED"}
def store_state(self): def store_state(self, context):
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"] areas = [a for a in context.screen.areas if a.type == "VIEW_3D"]
if areas: if areas:
self.transaction_data = {"area": areas[0], "color_type": areas[0].spaces[0].shading.color_type} self.transaction_data = {"area": areas[0], "color_type": areas[0].spaces[0].shading.color_type}
@@ -187,7 +188,7 @@ class ColourByPset(bpy.types.Operator):
def execute(self, context): def execute(self, context):
IfcStore.begin_transaction(self) IfcStore.begin_transaction(self)
self.store_state() self.store_state(context)
result = self._execute(context) result = self._execute(context)
IfcStore.add_transaction_operation(self) IfcStore.add_transaction_operation(self)
IfcStore.end_transaction(self) IfcStore.end_transaction(self)
@@ -218,13 +219,13 @@ class ColourByPset(bpy.types.Operator):
if value not in values: if value not in values:
values[value] = next(colours) values[value] = next(colours)
obj.color = values[value] obj.color = values[value]
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"] areas = [a for a in context.screen.areas if a.type == "VIEW_3D"]
if areas: if areas:
areas[0].spaces[0].shading.color_type = "OBJECT" areas[0].spaces[0].shading.color_type = "OBJECT"
return {"FINISHED"} return {"FINISHED"}
def store_state(self): def store_state(self, context):
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"] areas = [a for a in context.screen.areas if a.type == "VIEW_3D"]
if areas: if areas:
self.transaction_data = {"area": areas[0], "color_type": areas[0].spaces[0].shading.color_type} self.transaction_data = {"area": areas[0], "color_type": areas[0].spaces[0].shading.color_type}
@@ -244,7 +245,7 @@ class ColourByClass(bpy.types.Operator):
def execute(self, context): def execute(self, context):
IfcStore.begin_transaction(self) IfcStore.begin_transaction(self)
self.store_state() self.store_state(context)
result = self._execute(context) result = self._execute(context)
IfcStore.add_transaction_operation(self) IfcStore.add_transaction_operation(self)
IfcStore.end_transaction(self) IfcStore.end_transaction(self)
@@ -254,7 +255,7 @@ class ColourByClass(bpy.types.Operator):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
colours = cycle(colour_list) colours = cycle(colour_list)
ifc_classes = {} ifc_classes = {}
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
@@ -262,13 +263,13 @@ class ColourByClass(bpy.types.Operator):
if ifc_class not in ifc_classes: if ifc_class not in ifc_classes:
ifc_classes[ifc_class] = next(colours) ifc_classes[ifc_class] = next(colours)
obj.color = ifc_classes[ifc_class] obj.color = ifc_classes[ifc_class]
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"] areas = [a for a in context.screen.areas if a.type == "VIEW_3D"]
if areas: if areas:
areas[0].spaces[0].shading.color_type = "OBJECT" areas[0].spaces[0].shading.color_type = "OBJECT"
return {"FINISHED"} return {"FINISHED"}
def store_state(self): def store_state(self, context):
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"] areas = [a for a in context.screen.areas if a.type == "VIEW_3D"]
if areas: if areas:
self.transaction_data = {"area": areas[0], "color_type": areas[0].spaces[0].shading.color_type} self.transaction_data = {"area": areas[0], "color_type": areas[0].spaces[0].shading.color_type}
@@ -286,6 +287,6 @@ class ResetObjectColours(bpy.types.Operator):
bl_label = "Reset Colours" bl_label = "Reset Colours"
def execute(self, context): def execute(self, context):
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
obj.color = (1, 1, 1, 1) obj.color = (1, 1, 1, 1)
return {"FINISHED"} return {"FINISHED"}
@@ -753,7 +753,7 @@ class AssignProduct(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
relating_products = ( relating_products = (
[bpy.data.objects.get(self.relating_product)] if self.relating_product else bpy.context.selected_objects [bpy.data.objects.get(self.relating_product)] if self.relating_product else context.selected_objects
) )
for relating_product in relating_products: for relating_product in relating_products:
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -779,7 +779,7 @@ class UnassignProduct(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
relating_products = ( relating_products = (
[bpy.data.objects.get(self.relating_product)] if self.relating_product else bpy.context.selected_objects [bpy.data.objects.get(self.relating_product)] if self.relating_product else context.selected_objects
) )
for relating_product in relating_products: for relating_product in relating_products:
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -805,7 +805,7 @@ class AssignProcess(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects [bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
) )
for related_object in related_objects: for related_object in related_objects:
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -831,7 +831,7 @@ class UnassignProcess(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects [bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
) )
for related_object in related_objects: for related_object in related_objects:
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -864,10 +864,10 @@ class GenerateGanttChart(bpy.types.Operator):
} }
for task_id in Data.work_schedules[self.work_schedule]["RelatedObjects"]: for task_id in Data.work_schedules[self.work_schedule]["RelatedObjects"]:
self.create_new_task_json(task_id) self.create_new_task_json(task_id)
with open(os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html"), "w") as f: with open(os.path.join(context.scene.BIMProperties.data_dir, "gantt", "index.html"), "w") as f:
with open(os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.mustache"), "r") as t: with open(os.path.join(context.scene.BIMProperties.data_dir, "gantt", "index.mustache"), "r") as t:
f.write(pystache.render(t.read(), {"json_data": json.dumps(self.json)})) f.write(pystache.render(t.read(), {"json_data": json.dumps(self.json)}))
webbrowser.open("file://" + os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html")) webbrowser.open("file://" + os.path.join(context.scene.BIMProperties.data_dir, "gantt", "index.html"))
return {"FINISHED"} return {"FINISHED"}
def create_new_task_json(self, task_id): def create_new_task_json(self, task_id):
@@ -1568,7 +1568,7 @@ class SelectTaskRelatedProducts(bpy.types.Operator):
related_products = ifcopenshell.api.run( related_products = ifcopenshell.api.run(
"sequence.get_related_products", self.file, **{"related_object": self.file.by_id(self.task)} "sequence.get_related_products", self.file, **{"related_object": self.file.by_id(self.task)}
) )
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
obj.select_set(False) obj.select_set(False)
if obj.BIMObjectProperties.ifc_definition_id in related_products: if obj.BIMObjectProperties.ifc_definition_id in related_products:
obj.select_set(True) obj.select_set(True)
@@ -1644,7 +1644,7 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
self.finish = parser.parse(self.props.visualisation_finish, dayfirst=True, fuzzy=True) self.finish = parser.parse(self.props.visualisation_finish, dayfirst=True, fuzzy=True)
self.duration = self.finish - self.start self.duration = self.finish - self.start
self.start_frame = 1 self.start_frame = 1
self.total_frames = self.calculate_total_frames() self.total_frames = self.calculate_total_frames(context)
self.preprocess_tasks() self.preprocess_tasks()
for obj in bpy.data.objects: for obj in bpy.data.objects:
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
@@ -1742,7 +1742,7 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
obj.keyframe_insert(data_path="color", frame=product_frame["COMPLETED"]) obj.keyframe_insert(data_path="color", frame=product_frame["COMPLETED"])
obj.keyframe_insert(data_path="hide_viewport", frame=product_frame["COMPLETED"]) obj.keyframe_insert(data_path="hide_viewport", frame=product_frame["COMPLETED"])
def calculate_total_frames(self): def calculate_total_frames(self, context):
if self.props.speed_types == "FRAME_SPEED": if self.props.speed_types == "FRAME_SPEED":
return self.calculate_using_frames( return self.calculate_using_frames(
self.start, self.start,
@@ -1754,7 +1754,7 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
return self.calculate_using_duration( return self.calculate_using_duration(
self.start, self.start,
self.finish, self.finish,
bpy.context.scene.render.fps, context.scene.render.fps,
isodate.parse_duration(self.props.speed_animation_duration), isodate.parse_duration(self.props.speed_animation_duration),
isodate.parse_duration(self.props.speed_real_duration), isodate.parse_duration(self.props.speed_real_duration),
) )
@@ -1762,7 +1762,7 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
return self.calculate_using_multiplier( return self.calculate_using_multiplier(
self.start, self.start,
self.finish, self.finish,
bpy.context.scene.render.fps, context.scene.render.fps,
self.props.speed_multiplier, self.props.speed_multiplier,
) )
@@ -22,7 +22,7 @@ class AssignContainer(bpy.types.Operator):
active_object = context.active_object active_object = context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
related_elements = ( related_elements = (
[bpy.data.objects.get(self.related_element)] if self.related_element else bpy.context.selected_objects [bpy.data.objects.get(self.related_element)] if self.related_element else context.selected_objects
) )
sprops = context.scene.BIMSpatialProperties sprops = context.scene.BIMSpatialProperties
relating_structure = ( relating_structure = (
@@ -52,7 +52,7 @@ class AssignContainer(bpy.types.Operator):
relating_collection = bpy.data.collections.get(relating_structure_obj.name) relating_collection = bpy.data.collections.get(relating_structure_obj.name)
if aggregate_collection: if aggregate_collection:
self.remove_collection(bpy.context.scene.collection, aggregate_collection) self.remove_collection(context.scene.collection, aggregate_collection)
for collection in bpy.data.collections: for collection in bpy.data.collections:
self.remove_collection(collection, aggregate_collection) self.remove_collection(collection, aggregate_collection)
relating_collection.children.link(aggregate_collection) relating_collection.children.link(aggregate_collection)
@@ -77,7 +77,7 @@ class EnableEditingContainer(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
bpy.context.active_object.BIMObjectSpatialProperties.is_editing = True context.active_object.BIMObjectSpatialProperties.is_editing = True
getSpatialContainers(self, context) getSpatialContainers(self, context)
return {"FINISHED"} return {"FINISHED"}
@@ -100,7 +100,7 @@ class DisableEditingContainer(bpy.types.Operator):
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
obj.BIMObjectSpatialProperties.is_editing = False obj.BIMObjectSpatialProperties.is_editing = False
return {"FINISHED"} return {"FINISHED"}
@@ -115,7 +115,7 @@ class RemoveContainer(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
@@ -125,14 +125,14 @@ class RemoveContainer(bpy.types.Operator):
aggregate_collection = bpy.data.collections.get(obj.name) aggregate_collection = bpy.data.collections.get(obj.name)
if aggregate_collection: if aggregate_collection:
self.remove_collection(bpy.context.scene.collection, aggregate_collection) self.remove_collection(context.scene.collection, aggregate_collection)
for collection in bpy.data.collections: for collection in bpy.data.collections:
self.remove_collection(collection, spatial_collection) self.remove_collection(collection, spatial_collection)
bpy.context.scene.collection.children.link(aggregate_collection) context.scene.collection.children.link(aggregate_collection)
else: else:
for collection in obj.users_collection: for collection in obj.users_collection:
collection.objects.unlink(obj) collection.objects.unlink(obj)
bpy.context.scene.collection.objects.link(obj) context.scene.collection.objects.link(obj)
return {"FINISHED"} return {"FINISHED"}
def remove_collection(self, parent, child): def remove_collection(self, parent, child):
@@ -153,7 +153,7 @@ class CopyToContainer(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
objects = [bpy.data.objects.get(self.obj)] if self.obj else bpy.context.selected_objects objects = [bpy.data.objects.get(self.obj)] if self.obj else context.selected_objects
sprops = context.scene.BIMSpatialProperties sprops = context.scene.BIMSpatialProperties
container_ids = [c.ifc_definition_id for c in sprops.spatial_elements if c.is_selected] container_ids = [c.ifc_definition_id for c in sprops.spatial_elements if c.is_selected]
for obj in objects: for obj in objects:
@@ -20,7 +20,7 @@ class AddStructuralMemberConnection(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
file = IfcStore.get_file() file = IfcStore.get_file()
@@ -46,7 +46,7 @@ class EnableEditingStructuralConnectionCondition(bpy.types.Operator):
connects_structural_member: bpy.props.IntProperty() connects_structural_member: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
obj = bpy.context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
applied_condition_id = Data.connects_structural_members[self.connects_structural_member]["AppliedCondition"] applied_condition_id = Data.connects_structural_members[self.connects_structural_member]["AppliedCondition"]
@@ -60,7 +60,7 @@ class DisableEditingStructuralConnectionCondition(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
obj = bpy.context.active_object obj = context.active_object
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
props.active_connects_structural_member = 0 props.active_connects_structural_member = 0
return {"FINISHED"} return {"FINISHED"}
@@ -423,7 +423,7 @@ class EnableEditingStructuralItemAxis(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
obj = bpy.context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
@@ -463,7 +463,7 @@ class DisableEditingStructuralItemAxis(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
obj = bpy.context.active_object obj = context.active_object
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
props.is_editing_axis = False props.is_editing_axis = False
if props.axis_empty: if props.axis_empty:
@@ -479,7 +479,7 @@ class EditStructuralItemAxis(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
relative_matrix = props.axis_empty.matrix_world @ obj.matrix_world.inverted() relative_matrix = props.axis_empty.matrix_world @ obj.matrix_world.inverted()
@@ -501,7 +501,7 @@ class EnableEditingStructuralConnectionCS(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
obj = bpy.context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
@@ -553,7 +553,7 @@ class DisableEditingStructuralConnectionCS(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
obj = bpy.context.active_object obj = context.active_object
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
props.is_editing_connection_cs = False props.is_editing_connection_cs = False
if props.ccs_empty: if props.ccs_empty:
@@ -570,7 +570,7 @@ class EditStructuralConnectionCS(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
relative_matrix = props.ccs_empty.matrix_world @ obj.matrix_world.inverted() relative_matrix = props.ccs_empty.matrix_world @ obj.matrix_world.inverted()
@@ -31,7 +31,7 @@ def getApplicableStructuralLoadTypes(self, context):
element_classes = set( element_classes = set(
[ [
ifc_file.by_id(o.BIMObjectProperties.ifc_definition_id).is_a() ifc_file.by_id(o.BIMObjectProperties.ifc_definition_id).is_a()
for o in bpy.context.selected_objects for o in context.selected_objects
if o.BIMObjectProperties.ifc_definition_id if o.BIMObjectProperties.ifc_definition_id
] ]
) )
@@ -32,7 +32,7 @@ class UpdateStyleColours(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material material = bpy.data.materials.get(self.material) if self.material else context.active_object.active_material
settings = get_colour_settings(material) settings = get_colour_settings(material)
settings["style"] = self.file.by_id(material.BIMMaterialProperties.ifc_style_id) settings["style"] = self.file.by_id(material.BIMMaterialProperties.ifc_style_id)
ifcopenshell.api.run("style.edit_style_colours", self.file, **settings) ifcopenshell.api.run("style.edit_style_colours", self.file, **settings)
@@ -50,7 +50,7 @@ class RemoveStyle(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material material = bpy.data.materials.get(self.material) if self.material else context.active_object.active_material
ifcopenshell.api.run( ifcopenshell.api.run(
"style.remove_style", self.file, style=self.file.by_id(material.BIMMaterialProperties.ifc_style_id) "style.remove_style", self.file, style=self.file.by_id(material.BIMMaterialProperties.ifc_style_id)
) )
@@ -69,7 +69,7 @@ class AddStyle(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material material = bpy.data.materials.get(self.material) if self.material else context.active_object.active_material
settings = get_colour_settings(material) settings = get_colour_settings(material)
settings["name"] = material.name settings["name"] = material.name
settings["external_definition"] = None # TODO: Implement. See #1222 settings["external_definition"] = None # TODO: Implement. See #1222
@@ -108,7 +108,7 @@ class EnableEditingStyle(bpy.types.Operator):
material: bpy.props.StringProperty() material: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material material = bpy.data.materials.get(self.material) if self.material else context.active_object.active_material
props = material.BIMStyleProperties props = material.BIMStyleProperties
while len(props.attributes) > 0: while len(props.attributes) > 0:
props.attributes.remove(0) props.attributes.remove(0)
@@ -126,7 +126,7 @@ class DisableEditingStyle(bpy.types.Operator):
material: bpy.props.StringProperty() material: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material material = bpy.data.materials.get(self.material) if self.material else context.active_object.active_material
props = material.BIMStyleProperties props = material.BIMStyleProperties
props.is_editing_attributes = False props.is_editing_attributes = False
return {"FINISHED"} return {"FINISHED"}
@@ -141,7 +141,7 @@ class EditStyle(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
material = bpy.context.active_object.active_material material = context.active_object.active_material
props = material.BIMStyleProperties props = material.BIMStyleProperties
attributes = blenderbim.bim.helper.export_attributes(props.attributes) attributes = blenderbim.bim.helper.export_attributes(props.attributes)
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -186,7 +186,7 @@ class SelectSystemProducts(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
obj.select_set(False) obj.select_set(False)
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
@@ -24,7 +24,7 @@ class AssignType(bpy.types.Operator):
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] [bpy.data.objects.get(self.related_object)]
if self.related_object if self.related_object
else bpy.context.selected_objects or [bpy.context.active_object] else context.selected_objects or [context.active_object]
) )
for related_object in related_objects: for related_object in related_objects:
oprops = related_object.BIMObjectProperties oprops = related_object.BIMObjectProperties
@@ -72,7 +72,7 @@ class UnassignType(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
related_objects = ( related_objects = (
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects [bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
) )
for related_object in related_objects: for related_object in related_objects:
oprops = related_object.BIMObjectProperties oprops = related_object.BIMObjectProperties
@@ -93,7 +93,7 @@ class EnableEditingType(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
bpy.context.active_object.BIMTypeProperties.is_editing_type = True context.active_object.BIMTypeProperties.is_editing_type = True
return {"FINISHED"} return {"FINISHED"}
@@ -104,7 +104,7 @@ class DisableEditingType(bpy.types.Operator):
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
obj.BIMTypeProperties.is_editing_type = False obj.BIMTypeProperties.is_editing_type = False
return {"FINISHED"} return {"FINISHED"}
@@ -117,7 +117,7 @@ class SelectSimilarType(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
related_object = bpy.data.objects.get(self.related_object) if self.related_object else bpy.context.active_object related_object = bpy.data.objects.get(self.related_object) if self.related_object else context.active_object
oprops = related_object.BIMObjectProperties oprops = related_object.BIMObjectProperties
product = self.file.by_id(oprops.ifc_definition_id) product = self.file.by_id(oprops.ifc_definition_id)
declaration = IfcStore.get_schema().declaration_by_name(product.is_a()) declaration = IfcStore.get_schema().declaration_by_name(product.is_a())
@@ -129,7 +129,7 @@ class SelectSimilarType(bpy.types.Operator):
related_objects = ifcopenshell.api.run( related_objects = ifcopenshell.api.run(
"type.get_related_objects", self.file, **{"related_object": self.file.by_id(oprops.ifc_definition_id)} "type.get_related_objects", self.file, **{"related_object": self.file.by_id(oprops.ifc_definition_id)}
) )
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
if obj.BIMObjectProperties.ifc_definition_id in related_objects: if obj.BIMObjectProperties.ifc_definition_id in related_objects:
obj.select_set(True) obj.select_set(True)
return {"FINISHED"} return {"FINISHED"}
@@ -143,10 +143,10 @@ class SelectTypeObjects(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
relating_type = bpy.data.objects.get(self.relating_type) if self.relating_type else bpy.context.active_object relating_type = bpy.data.objects.get(self.relating_type) if self.relating_type else context.active_object
oprops = relating_type.BIMObjectProperties oprops = relating_type.BIMObjectProperties
related_objects = Data.types[oprops.ifc_definition_id] related_objects = Data.types[oprops.ifc_definition_id]
for obj in bpy.context.visible_objects: for obj in context.visible_objects:
if obj.BIMObjectProperties.ifc_definition_id in related_objects: if obj.BIMObjectProperties.ifc_definition_id in related_objects:
obj.select_set(True) obj.select_set(True)
return {"FINISHED"} return {"FINISHED"}
@@ -13,26 +13,27 @@ class AssignUnit(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
ifcopenshell.api.run("unit.assign_unit", IfcStore.get_file(), **self.get_units()) ifcopenshell.api.run("unit.assign_unit", IfcStore.get_file(), **self.get_units(context))
Data.load(IfcStore.get_file()) Data.load(IfcStore.get_file())
return {"FINISHED"} return {"FINISHED"}
def get_units(self): def get_units(self, context):
scene = context.scene
units = { units = {
"length": { "length": {
"ifc": None, "ifc": None,
"is_metric": bpy.context.scene.unit_settings.system != "IMPERIAL", "is_metric": scene.unit_settings.system != "IMPERIAL",
"raw": bpy.context.scene.unit_settings.length_unit, "raw": scene.unit_settings.length_unit,
}, },
"area": { "area": {
"ifc": None, "ifc": None,
"is_metric": bpy.context.scene.unit_settings.system != "IMPERIAL", "is_metric": scene.unit_settings.system != "IMPERIAL",
"raw": bpy.context.scene.unit_settings.length_unit, "raw": scene.unit_settings.length_unit,
}, },
"volume": { "volume": {
"ifc": None, "ifc": None,
"is_metric": bpy.context.scene.unit_settings.system != "IMPERIAL", "is_metric": scene.unit_settings.system != "IMPERIAL",
"raw": bpy.context.scene.unit_settings.length_unit, "raw": scene.unit_settings.length_unit,
}, },
} }
for data in units.values(): for data in units.values():
@@ -16,7 +16,7 @@ class AddOpening(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
opening = bpy.data.objects.get(self.opening) opening = bpy.data.objects.get(self.opening)
opening.display_type = "WIRE" opening.display_type = "WIRE"
if not opening.BIMObjectProperties.ifc_definition_id: if not opening.BIMObjectProperties.ifc_definition_id:
@@ -69,7 +69,7 @@ class RemoveOpening(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
for modifier in obj.modifiers: for modifier in obj.modifiers:
if modifier.type != "BOOLEAN": if modifier.type != "BOOLEAN":
@@ -97,7 +97,7 @@ class AddFilling(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
opening = bpy.data.objects.get(self.opening) if self.opening else context.scene.VoidProperties.desired_opening opening = bpy.data.objects.get(self.opening) if self.opening else context.scene.VoidProperties.desired_opening
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
element_id = obj.BIMObjectProperties.ifc_definition_id element_id = obj.BIMObjectProperties.ifc_definition_id
@@ -123,7 +123,7 @@ class RemoveFilling(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context) return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"void.remove_filling", self.file, **{"element": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)} "void.remove_filling", self.file, **{"element": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)}
@@ -138,7 +138,7 @@ class ToggleOpeningVisibility(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
for project in [c for c in bpy.context.view_layer.layer_collection.children if "IfcProject" in c.name]: for project in [c for c in context.view_layer.layer_collection.children if "IfcProject" in c.name]:
for collection in [c for c in project.children if "IfcOpeningElements" in c.name]: for collection in [c for c in project.children if "IfcOpeningElements" in c.name]:
collection.hide_viewport = not collection.hide_viewport collection.hide_viewport = not collection.hide_viewport
return {"FINISHED"} return {"FINISHED"}
+60 -59
View File
@@ -29,8 +29,8 @@ class ExportIFC(bpy.types.Operator):
if not IfcStore.get_file(): if not IfcStore.get_file():
self.report({"ERROR"}, "No IFC project is available for export - create or import a project first.") self.report({"ERROR"}, "No IFC project is available for export - create or import a project first.")
return {"FINISHED"} return {"FINISHED"}
if bpy.context.scene.BIMProperties.ifc_file: if context.scene.BIMProperties.ifc_file:
self.filepath = bpy.context.scene.BIMProperties.ifc_file self.filepath = context.scene.BIMProperties.ifc_file
return self.execute(context) return self.execute(context)
if not self.filepath: if not self.filepath:
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".ifc") self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".ifc")
@@ -69,11 +69,12 @@ class ExportIFC(bpy.types.Operator):
ifc_exporter.export() ifc_exporter.export()
settings.logger.info("Export finished in {:.2f} seconds".format(time.time() - start)) settings.logger.info("Export finished in {:.2f} seconds".format(time.time() - start))
print("Export finished in {:.2f} seconds".format(time.time() - start)) print("Export finished in {:.2f} seconds".format(time.time() - start))
if not bpy.context.scene.DocProperties.ifc_files: scene = context.scene
new = bpy.context.scene.DocProperties.ifc_files.add() if not scene.DocProperties.ifc_files:
new = scene.DocProperties.ifc_files.add()
new.name = output_file new.name = output_file
if not bpy.context.scene.BIMProperties.ifc_file: if not scene.BIMProperties.ifc_file:
bpy.context.scene.BIMProperties.ifc_file = output_file scene.BIMProperties.ifc_file = output_file
if bpy.data.is_saved and bpy.data.is_dirty and bpy.data.filepath: if bpy.data.is_saved and bpy.data.is_dirty and bpy.data.filepath:
bpy.ops.wm.save_mainfile(filepath=bpy.data.filepath) bpy.ops.wm.save_mainfile(filepath=bpy.data.filepath)
return {"FINISHED"} return {"FINISHED"}
@@ -109,8 +110,8 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
def execute(self, context): def execute(self, context):
start = time.time() start = time.time()
logger = logging.getLogger("ImportIFC") logger = logging.getLogger("ImportIFC")
path_log = os.path.join(bpy.context.scene.BIMProperties.data_dir, "process.log"), path_log = os.path.join(context.scene.BIMProperties.data_dir, "process.log"),
if not os.access(bpy.context.scene.BIMProperties.data_dir, os.W_OK): if not os.access(context.scene.BIMProperties.data_dir, os.W_OK):
path_log = os.path.join(tempfile.mkdtemp(), "process.log") path_log = os.path.join(tempfile.mkdtemp(), "process.log")
logging.basicConfig( logging.basicConfig(
filename=path_log, filename=path_log,
@@ -161,7 +162,7 @@ class SelectIfcFile(bpy.types.Operator):
def execute(self, context): def execute(self, context):
if os.path.exists(self.filepath) and "ifc" in os.path.splitext(self.filepath)[1]: if os.path.exists(self.filepath) and "ifc" in os.path.splitext(self.filepath)[1]:
bpy.context.scene.BIMProperties.ifc_file = self.filepath context.scene.BIMProperties.ifc_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -176,7 +177,7 @@ class SelectDataDir(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.BIMProperties.data_dir = os.path.dirname(self.filepath) context.scene.BIMProperties.data_dir = os.path.dirname(self.filepath)
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -191,7 +192,7 @@ class SelectSchemaDir(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
bpy.context.scene.BIMProperties.schema_dir = os.path.dirname(self.filepath) context.scene.BIMProperties.schema_dir = os.path.dirname(self.filepath)
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -222,36 +223,36 @@ class AddSectionPlane(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
obj = self.create_section_obj() obj = self.create_section_obj(context)
if not self.has_section_override_node(): if not self.has_section_override_node():
self.create_section_compare_node() self.create_section_compare_node()
self.create_section_override_node(obj) self.create_section_override_node(obj, context)
else: else:
self.append_obj_to_section_override_node(obj) self.append_obj_to_section_override_node(obj)
self.add_default_material_if_none_exists() self.add_default_material_if_none_exists(context)
self.override_materials() self.override_materials()
return {"FINISHED"} return {"FINISHED"}
def create_section_obj(self): def create_section_obj(self, context):
section = bpy.data.objects.new("Section", None) section = bpy.data.objects.new("Section", None)
section.empty_display_type = "SINGLE_ARROW" section.empty_display_type = "SINGLE_ARROW"
section.empty_display_size = 5 section.empty_display_size = 5
section.show_in_front = True section.show_in_front = True
if ( if (
bpy.context.active_object context.active_object
and bpy.context.active_object.select_get() and context.active_object.select_get()
and isinstance(bpy.context.active_object.data, bpy.types.Camera) and isinstance(context.active_object.data, bpy.types.Camera)
): ):
section.matrix_world = ( section.matrix_world = (
bpy.context.active_object.matrix_world @ Euler((radians(180.0), 0.0, 0.0), "XYZ").to_matrix().to_4x4() context.active_object.matrix_world @ Euler((radians(180.0), 0.0, 0.0), "XYZ").to_matrix().to_4x4()
) )
else: else:
section.rotation_euler = Euler((radians(180.0), 0.0, 0.0), "XYZ") section.rotation_euler = Euler((radians(180.0), 0.0, 0.0), "XYZ")
section.location = bpy.context.scene.cursor.location section.location = context.scene.cursor.location
collection = bpy.data.collections.get("Sections") collection = bpy.data.collections.get("Sections")
if not collection: if not collection:
collection = bpy.data.collections.new("Sections") collection = bpy.data.collections.new("Sections")
bpy.context.scene.collection.children.link(collection) context.scene.collection.children.link(collection)
collection.objects.link(section) collection.objects.link(section)
return section return section
@@ -283,7 +284,7 @@ class AddSectionPlane(bpy.types.Operator):
group.links.new(add.outputs[0], compare.inputs[0]) group.links.new(add.outputs[0], compare.inputs[0])
group.links.new(compare.outputs[0], group_output.inputs[""]) group.links.new(compare.outputs[0], group_output.inputs[""])
def create_section_override_node(self, obj): def create_section_override_node(self, obj, context):
group = bpy.data.node_groups.new("Section Override", type="ShaderNodeTree") group = bpy.data.node_groups.new("Section Override", type="ShaderNodeTree")
group_input = group.nodes.new(type="NodeGroupInput") group_input = group.nodes.new(type="NodeGroupInput")
@@ -292,7 +293,7 @@ class AddSectionPlane(bpy.types.Operator):
backfacing = group.nodes.new(type="ShaderNodeNewGeometry") backfacing = group.nodes.new(type="ShaderNodeNewGeometry")
backfacing_mix = group.nodes.new(type="ShaderNodeMixShader") backfacing_mix = group.nodes.new(type="ShaderNodeMixShader")
emission = group.nodes.new(type="ShaderNodeEmission") emission = group.nodes.new(type="ShaderNodeEmission")
emission.inputs[0].default_value = list(bpy.context.scene.BIMProperties.section_plane_colour) + [1] emission.inputs[0].default_value = list(context.scene.BIMProperties.section_plane_colour) + [1]
group.links.new(backfacing.outputs["Backfacing"], backfacing_mix.inputs[0]) group.links.new(backfacing.outputs["Backfacing"], backfacing_mix.inputs[0])
group.links.new(group_input.outputs[""], backfacing_mix.inputs[1]) group.links.new(group_input.outputs[""], backfacing_mix.inputs[1])
@@ -337,16 +338,16 @@ class AddSectionPlane(bpy.types.Operator):
section_compare.name = "Last Section Compare" section_compare.name = "Last Section Compare"
def add_default_material_if_none_exists(self): def add_default_material_if_none_exists(self, context):
material = bpy.data.materials.get("Section Override") material = bpy.data.materials.get("Section Override")
if not material: if not material:
material = bpy.data.materials.new("Section Override") material = bpy.data.materials.new("Section Override")
material.use_nodes = True material.use_nodes = True
if bpy.context.scene.BIMProperties.should_section_selected_objects: if context.scene.BIMProperties.should_section_selected_objects:
objects = list(bpy.context.selected_objects) objects = list(context.selected_objects)
else: else:
objects = list(bpy.context.visible_objects) objects = list(context.visible_objects)
for obj in objects: for obj in objects:
aggregate = obj.instance_collection aggregate = obj.instance_collection
@@ -390,7 +391,7 @@ class RemoveSectionPlane(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
name = bpy.context.active_object.name name = context.active_object.name
section_override = bpy.data.node_groups.get("Section Override") section_override = bpy.data.node_groups.get("Section Override")
if not section_override: if not section_override:
return {"FINISHED"} return {"FINISHED"}
@@ -406,7 +407,7 @@ class RemoveSectionPlane(bpy.types.Operator):
else: # If it links to section_compare.inputs[0] else: # If it links to section_compare.inputs[0]
if section_compare.inputs[1].links[0].from_node.name == "Mock Section": if section_compare.inputs[1].links[0].from_node.name == "Mock Section":
# Then it is the very last section. Purge everything. # Then it is the very last section. Purge everything.
self.purge_all_section_data() self.purge_all_section_data(context)
return {"FINISHED"} return {"FINISHED"}
section_override.links.new( section_override.links.new(
section_compare.inputs[1].links[0].from_socket, section_compare.outputs[0].links[0].to_socket section_compare.inputs[1].links[0].from_socket, section_compare.outputs[0].links[0].to_socket
@@ -419,10 +420,10 @@ class RemoveSectionPlane(bpy.types.Operator):
section_mix = section_override.nodes.get("Section Mix") section_mix = section_override.nodes.get("Section Mix")
new_last_compare = section_mix.inputs[0].links[0].from_node new_last_compare = section_mix.inputs[0].links[0].from_node
new_last_compare.name = "Last Section Compare" new_last_compare.name = "Last Section Compare"
bpy.ops.object.delete({"selected_objects": [bpy.context.active_object]}) bpy.ops.object.delete({"selected_objects": [context.active_object]})
return {"FINISHED"} return {"FINISHED"}
def purge_all_section_data(self): def purge_all_section_data(self, context):
bpy.data.materials.remove(bpy.data.materials.get("Section Override")) bpy.data.materials.remove(bpy.data.materials.get("Section Override"))
for material in bpy.data.materials: for material in bpy.data.materials:
if not material.node_tree: if not material.node_tree:
@@ -436,7 +437,7 @@ class RemoveSectionPlane(bpy.types.Operator):
material.node_tree.nodes.remove(override) material.node_tree.nodes.remove(override)
bpy.data.node_groups.remove(bpy.data.node_groups.get("Section Override")) bpy.data.node_groups.remove(bpy.data.node_groups.get("Section Override"))
bpy.data.node_groups.remove(bpy.data.node_groups.get("Section Compare")) bpy.data.node_groups.remove(bpy.data.node_groups.get("Section Compare"))
bpy.ops.object.delete({"selected_objects": [bpy.context.active_object]}) bpy.ops.object.delete({"selected_objects": [context.active_object]})
class ReloadIfcFile(bpy.types.Operator): class ReloadIfcFile(bpy.types.Operator):
@@ -455,7 +456,7 @@ class AddIfcFile(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
bpy.context.scene.DocProperties.ifc_files.add() context.scene.DocProperties.ifc_files.add()
return {"FINISHED"} return {"FINISHED"}
@@ -466,7 +467,7 @@ class RemoveIfcFile(bpy.types.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def execute(self, context):
bpy.context.scene.DocProperties.ifc_files.remove(self.index) context.scene.DocProperties.ifc_files.remove(self.index)
return {"FINISHED"} return {"FINISHED"}
@@ -477,9 +478,9 @@ class SetOverrideColour(bpy.types.Operator):
def execute(self, context): def execute(self, context):
result = 0 result = 0
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
obj.color = bpy.context.scene.BIMProperties.override_colour obj.color = context.scene.BIMProperties.override_colour
area = next(area for area in bpy.context.screen.areas if area.type == "VIEW_3D") area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
area.spaces[0].shading.color_type = "OBJECT" area.spaces[0].shading.color_type = "OBJECT"
return {"FINISHED"} return {"FINISHED"}
@@ -505,7 +506,7 @@ class LinkIfc(bpy.types.Operator):
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
def execute(self, context): def execute(self, context):
# bpy.context.active_object.active_material.BIMMaterialProperties.location = self.filepath # context.active_object.active_material.BIMMaterialProperties.location = self.filepath
# coll_name = "MyCollection" # coll_name = "MyCollection"
with bpy.data.libraries.load(self.filepath, link=True) as (data_from, data_to): with bpy.data.libraries.load(self.filepath, link=True) as (data_from, data_to):
@@ -534,13 +535,13 @@ class SnapSpacesTogether(bpy.types.Operator):
def execute(self, context): def execute(self, context):
threshold = 0.5 threshold = 0.5
processed_polygons = set() processed_polygons = set()
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if obj.type != "MESH": if obj.type != "MESH":
continue continue
for polygon in obj.data.polygons: for polygon in obj.data.polygons:
center = obj.matrix_world @ polygon.center center = obj.matrix_world @ polygon.center
distance = None distance = None
for obj2 in bpy.context.selected_objects: for obj2 in context.selected_objects:
if obj2 == obj or obj.type != "MESH": if obj2 == obj or obj.type != "MESH":
continue continue
result = obj2.ray_cast(obj2.matrix_world.inverted() @ center, polygon.normal, distance=threshold) result = obj2.ray_cast(obj2.matrix_world.inverted() @ center, polygon.normal, distance=threshold)
@@ -576,7 +577,7 @@ class SelectExternalMaterialDir(bpy.types.Operator):
def execute(self, context): def execute(self, context):
# TODO: this is dead code, awaiting reimplementation. See #1222. # TODO: this is dead code, awaiting reimplementation. See #1222.
bpy.context.active_object.active_material.BIMMaterialProperties.location = self.filepath context.active_object.active_material.BIMMaterialProperties.location = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -590,28 +591,28 @@ class FetchExternalMaterial(bpy.types.Operator):
def execute(self, context): def execute(self, context):
# TODO: this is dead code, awaiting reimplementation. See #1222. # TODO: this is dead code, awaiting reimplementation. See #1222.
location = bpy.context.active_object.active_material.BIMMaterialProperties.location location = context.active_object.active_material.BIMMaterialProperties.location
if location[-6:] != ".mpass": if location[-6:] != ".mpass":
return {"FINISHED"} return {"FINISHED"}
if not os.path.isabs(location): if not os.path.isabs(location):
location = os.path.join(bpy.context.scene.BIMProperties.data_dir, location) location = os.path.join(context.scene.BIMProperties.data_dir, location)
with open(location) as f: with open(location) as f:
self.material_pass = json.load(f) self.material_pass = json.load(f)
if bpy.context.scene.render.engine == "BLENDER_EEVEE" and "eevee" in self.material_pass: if context.scene.render.engine == "BLENDER_EEVEE" and "eevee" in self.material_pass:
self.fetch_eevee_or_cycles("eevee") self.fetch_eevee_or_cycles("eevee", context)
elif bpy.context.scene.render.engine == "CYCLES" and "cycles" in self.material_pass: elif context.scene.render.engine == "CYCLES" and "cycles" in self.material_pass:
self.fetch_eevee_or_cycles("cycles") self.fetch_eevee_or_cycles("cycles", context)
return {"FINISHED"} return {"FINISHED"}
def fetch_eevee_or_cycles(self, name): def fetch_eevee_or_cycles(self, name, context):
identification = bpy.context.active_object.active_material.BIMMaterialProperties.identification identification = context.active_object.active_material.BIMMaterialProperties.identification
uri = self.material_pass[name]["uri"] uri = self.material_pass[name]["uri"]
if not os.path.isabs(uri): if not os.path.isabs(uri):
uri = os.path.join(bpy.context.scene.BIMProperties.data_dir, uri) uri = os.path.join(context.scene.BIMProperties.data_dir, uri)
bpy.ops.wm.link(filename=identification, directory=os.path.join(uri, "Material")) bpy.ops.wm.link(filename=identification, directory=os.path.join(uri, "Material"))
for material in bpy.data.materials: for material in bpy.data.materials:
if material.name == identification and material.library: if material.name == identification and material.library:
bpy.context.active_object.material_slots[0].material = material context.active_object.material_slots[0].material = material
return return
@@ -621,15 +622,15 @@ class FetchObjectPassport(bpy.types.Operator):
def execute(self, context): def execute(self, context):
# TODO: this is dead code, awaiting reimplementation. See #1222. # TODO: this is dead code, awaiting reimplementation. See #1222.
for reference in bpy.context.active_object.BIMObjectProperties.document_references: for reference in context.active_object.BIMObjectProperties.document_references:
reference = bpy.context.scene.BIMProperties.document_references[reference.name] reference = context.scene.BIMProperties.document_references[reference.name]
if reference.location[-6:] == ".blend": if reference.location[-6:] == ".blend":
self.fetch_blender(reference) self.fetch_blender(reference, context)
return {"FINISHED"} return {"FINISHED"}
def fetch_blender(self, reference): def fetch_blender(self, reference, context):
bpy.ops.wm.link(filename=reference.name, directory=os.path.join(reference.location, "Mesh")) bpy.ops.wm.link(filename=reference.name, directory=os.path.join(reference.location, "Mesh"))
bpy.context.active_object.data = bpy.data.meshes[reference.name] context.active_object.data = bpy.data.meshes[reference.name]
class CopyPropertyToSelection(bpy.types.Operator): class CopyPropertyToSelection(bpy.types.Operator):
@@ -641,7 +642,7 @@ class CopyPropertyToSelection(bpy.types.Operator):
def execute(self, context): def execute(self, context):
# TODO: this is dead code, awaiting reimplementation. See #1222. # TODO: this is dead code, awaiting reimplementation. See #1222.
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if "/" not in obj.name: if "/" not in obj.name:
continue continue
pset = obj.BIMObjectProperties.psets.get(self.pset_name) pset = obj.BIMObjectProperties.psets.get(self.pset_name)
@@ -671,9 +672,9 @@ class CopyAttributeToSelection(bpy.types.Operator):
def execute(self, context): def execute(self, context):
# TODO: this is dead code, awaiting reimplementation. See #1222. # TODO: this is dead code, awaiting reimplementation. See #1222.
self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(bpy.context.scene.BIMProperties.export_schema) self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(context.scene.BIMProperties.export_schema)
self.applicable_attributes_cache = {} self.applicable_attributes_cache = {}
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if "/" not in obj.name: if "/" not in obj.name:
continue continue
attribute = obj.BIMObjectProperties.attributes.get(self.attribute_name) attribute = obj.BIMObjectProperties.attributes.get(self.attribute_name)
+3 -3
View File
@@ -15,7 +15,7 @@ class BIM_PT_section_plane(Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.use_property_split = True layout.use_property_split = True
props = bpy.context.scene.BIMProperties props = context.scene.BIMProperties
row = layout.row() row = layout.row()
row.prop(props, "should_section_selected_objects") row.prop(props, "should_section_selected_objects")
@@ -91,7 +91,7 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
def ifc_units(self, context): def ifc_units(self, context):
scene = context.scene scene = context.scene
props = context.scene.BIMProperties props = scene.BIMProperties
layout = self.layout layout = self.layout
layout.use_property_decorate = False layout.use_property_decorate = False
layout.use_property_split = True layout.use_property_split = True
@@ -100,7 +100,7 @@ def ifc_units(self, context):
row = layout.row() row = layout.row()
row.prop(props, "volume_unit") row.prop(props, "volume_unit")
row = layout.row() row = layout.row()
if bpy.context.scene.unit_settings.system == "IMPERIAL": if scene.unit_settings.system == "IMPERIAL":
row.prop(props, "imperial_precision") row.prop(props, "imperial_precision")
else: else:
row.prop(props, "metric_precision") row.prop(props, "metric_precision")