mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-23 19:36:21 +00:00
Fix bug where BlenderBIM Add-on BCF module was completely broken. Now works with latest BCF library for BCF-XML v2.
This commit is contained in:
@@ -20,43 +20,44 @@ import bpy
|
|||||||
from . import ui, prop, operator
|
from . import ui, prop, operator
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
operator.NewBcfProject,
|
|
||||||
operator.LoadBcfProject,
|
|
||||||
operator.LoadBcfTopics,
|
|
||||||
operator.LoadBcfTopic,
|
|
||||||
operator.LoadBcfComments,
|
|
||||||
operator.EditBcfProjectName,
|
|
||||||
operator.EditBcfAuthor,
|
|
||||||
operator.EditBcfTopicName,
|
|
||||||
operator.EditBcfTopic,
|
|
||||||
operator.SaveBcfProject,
|
|
||||||
operator.AddBcfTopic,
|
|
||||||
operator.AddBcfHeaderFile,
|
|
||||||
operator.AddBcfBimSnippet,
|
|
||||||
operator.AddBcfReferenceLink,
|
|
||||||
operator.AddBcfDocumentReference,
|
|
||||||
operator.AddBcfLabel,
|
|
||||||
operator.AddBcfRelatedTopic,
|
|
||||||
operator.ViewBcfTopic,
|
|
||||||
operator.RemoveBcfTopic,
|
|
||||||
operator.RemoveBcfComment,
|
|
||||||
operator.RemoveBcfBimSnippet,
|
|
||||||
operator.RemoveBcfReferenceLink,
|
|
||||||
operator.RemoveBcfDocumentReference,
|
|
||||||
operator.RemoveBcfRelatedTopic,
|
|
||||||
operator.EditBcfReferenceLinks,
|
|
||||||
operator.EditBcfLabels,
|
|
||||||
operator.RemoveBcfLabel,
|
|
||||||
operator.EditBcfComment,
|
|
||||||
operator.AddBcfComment,
|
|
||||||
operator.ActivateBcfViewpoint,
|
operator.ActivateBcfViewpoint,
|
||||||
|
operator.AddBcfBimSnippet,
|
||||||
|
operator.AddBcfComment,
|
||||||
|
operator.AddBcfDocumentReference,
|
||||||
|
operator.AddBcfHeaderFile,
|
||||||
|
operator.AddBcfLabel,
|
||||||
|
operator.AddBcfReferenceLink,
|
||||||
|
operator.AddBcfRelatedTopic,
|
||||||
|
operator.AddBcfTopic,
|
||||||
operator.AddBcfViewpoint,
|
operator.AddBcfViewpoint,
|
||||||
operator.RemoveBcfViewpoint,
|
operator.EditBcfAuthor,
|
||||||
operator.RemoveBcfFile,
|
operator.EditBcfComment,
|
||||||
|
operator.EditBcfLabels,
|
||||||
|
operator.EditBcfProjectName,
|
||||||
|
operator.EditBcfReferenceLinks,
|
||||||
|
operator.EditBcfTopic,
|
||||||
|
operator.EditBcfTopicName,
|
||||||
|
operator.ExtractBcfFile,
|
||||||
|
operator.LoadBcfComments,
|
||||||
|
operator.LoadBcfProject,
|
||||||
|
operator.LoadBcfTopic,
|
||||||
|
operator.LoadBcfTopics,
|
||||||
|
operator.NewBcfProject,
|
||||||
operator.OpenBcfReferenceLink,
|
operator.OpenBcfReferenceLink,
|
||||||
operator.SelectBcfHeaderFile,
|
operator.RemoveBcfBimSnippet,
|
||||||
|
operator.RemoveBcfComment,
|
||||||
|
operator.RemoveBcfDocumentReference,
|
||||||
|
operator.RemoveBcfFile,
|
||||||
|
operator.RemoveBcfLabel,
|
||||||
|
operator.RemoveBcfReferenceLink,
|
||||||
|
operator.RemoveBcfRelatedTopic,
|
||||||
|
operator.RemoveBcfTopic,
|
||||||
|
operator.RemoveBcfViewpoint,
|
||||||
|
operator.SaveBcfProject,
|
||||||
operator.SelectBcfBimSnippetReference,
|
operator.SelectBcfBimSnippetReference,
|
||||||
operator.SelectBcfDocumentReference,
|
operator.SelectBcfDocumentReference,
|
||||||
|
operator.SelectBcfHeaderFile,
|
||||||
|
operator.ViewBcfTopic,
|
||||||
prop.BcfReferenceLink,
|
prop.BcfReferenceLink,
|
||||||
prop.BcfLabel,
|
prop.BcfLabel,
|
||||||
prop.BcfBimSnippet,
|
prop.BcfBimSnippet,
|
||||||
|
|||||||
@@ -20,14 +20,20 @@ import os
|
|||||||
import bpy
|
import bpy
|
||||||
import bcf
|
import bcf
|
||||||
import bcf.bcfxml
|
import bcf.bcfxml
|
||||||
|
import bcf.v2.model
|
||||||
|
import uuid
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import tempfile
|
||||||
|
import webbrowser
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
from . import bcfstore
|
|
||||||
import blenderbim.bim.module.bcf.prop as bcf_prop
|
import blenderbim.bim.module.bcf.prop as bcf_prop
|
||||||
|
from . import bcfstore
|
||||||
|
from pathlib import Path
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from math import radians, degrees, atan, tan, cos, sin
|
from math import radians, degrees, atan, tan, cos, sin
|
||||||
from mathutils import Vector, Matrix, Euler, geometry
|
from mathutils import Vector, Matrix, Euler, geometry
|
||||||
|
from xsdata.models.datatype import XmlDateTime
|
||||||
|
|
||||||
|
|
||||||
class NewBcfProject(bpy.types.Operator):
|
class NewBcfProject(bpy.types.Operator):
|
||||||
@@ -56,7 +62,6 @@ class LoadBcfProject(bpy.types.Operator):
|
|||||||
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()
|
|
||||||
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()
|
||||||
context.scene.BCFProperties.is_loaded = True
|
context.scene.BCFProperties.is_loaded = True
|
||||||
@@ -74,7 +79,6 @@ 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()
|
|
||||||
context.scene.BCFProperties.topics.clear()
|
context.scene.BCFProperties.topics.clear()
|
||||||
for index, topic_guid in enumerate(bcfxml.topics.keys()):
|
for index, topic_guid in enumerate(bcfxml.topics.keys()):
|
||||||
new = context.scene.BCFProperties.topics.add()
|
new = context.scene.BCFProperties.topics.add()
|
||||||
@@ -91,7 +95,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.topics[self.topic_guid]
|
||||||
bcfxml.get_header(self.topic_guid)
|
bcfxml.get_header(self.topic_guid)
|
||||||
new = context.scene.BCFProperties.topics[self.topic_index]
|
new = context.scene.BCFProperties.topics[self.topic_index]
|
||||||
data_map = {
|
data_map = {
|
||||||
@@ -125,10 +129,10 @@ class LoadBcfTopic(bpy.types.Operator):
|
|||||||
|
|
||||||
if topic.topic.bim_snippet:
|
if topic.topic.bim_snippet:
|
||||||
data_map = {
|
data_map = {
|
||||||
"type": topic.bim_snippet.snippet_type,
|
"type": topic.topic.bim_snippet.snippet_type,
|
||||||
"is_external": topic.bim_snippet.is_external,
|
"is_external": topic.topic.bim_snippet.is_external,
|
||||||
"reference": topic.bim_snippet.reference,
|
"reference": topic.topic.bim_snippet.reference,
|
||||||
"schema": topic.bim_snippet.reference_schema,
|
"schema": topic.topic.bim_snippet.reference_schema,
|
||||||
}
|
}
|
||||||
for key, value in data_map.items():
|
for key, value in data_map.items():
|
||||||
if value is not None:
|
if value is not None:
|
||||||
@@ -164,10 +168,9 @@ 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)
|
|
||||||
blender_topic = context.scene.BCFProperties.topics.get(self.topic_guid)
|
blender_topic = context.scene.BCFProperties.topics.get(self.topic_guid)
|
||||||
blender_topic.comments.clear()
|
blender_topic.comments.clear()
|
||||||
for comment in bcfxml.topics[self.topic_guid].comments.values():
|
for comment in bcfxml.topics[self.topic_guid].comments:
|
||||||
new = blender_topic.comments.add()
|
new = blender_topic.comments.add()
|
||||||
data_map = {
|
data_map = {
|
||||||
"name": comment.guid,
|
"name": comment.guid,
|
||||||
@@ -192,7 +195,6 @@ 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 = context.scene.BCFProperties.name
|
bcfxml.project.name = context.scene.BCFProperties.name
|
||||||
bcfxml.edit_project()
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -218,7 +220,6 @@ class EditBcfTopicName(bpy.types.Operator):
|
|||||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
topic.title = blender_topic.title
|
topic.title = blender_topic.title
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -242,7 +243,6 @@ class EditBcfTopic(bpy.types.Operator):
|
|||||||
topic.topic_status = blender_topic.status or None
|
topic.topic_status = blender_topic.status or None
|
||||||
topic.topic_type = blender_topic.type or None
|
topic.topic_type = blender_topic.type or None
|
||||||
|
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
props.refresh_topic(context)
|
props.refresh_topic(context)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ class SaveBcfProject(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||||
bcfxml.save_project(self.filepath)
|
bcfxml.save(self.filepath)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
@@ -299,15 +299,17 @@ class AddBcfBimSnippet(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
bim_snippet = bcf.v2.data.BimSnippet()
|
is_external = "://" in props.bim_snippet_reference
|
||||||
bim_snippet.reference = props.bim_snippet_reference
|
bim_snippet = bcf.v2.model.BimSnippet(
|
||||||
bim_snippet.reference_schema = props.bim_snippet_schema
|
reference=props.bim_snippet_reference if is_external else Path(props.bim_snippet_reference).name,
|
||||||
bim_snippet.snippet_type = props.bim_snippet_type
|
reference_schema=props.bim_snippet_schema,
|
||||||
bcfxml.add_bim_snippet(topic, bim_snippet)
|
snippet_type=props.bim_snippet_type,
|
||||||
|
is_external=is_external,
|
||||||
|
)
|
||||||
|
topic.topic.bim_snippet = bim_snippet
|
||||||
|
with open(props.bim_snippet_reference, "r") as f:
|
||||||
|
topic.bim_snippet = f.read()
|
||||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||||
bim_snippet.reference = ""
|
|
||||||
bim_snippet.reference_schema = ""
|
|
||||||
bim_snippet.snippet_type = ""
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -326,15 +328,14 @@ class AddBcfRelatedTopic(bpy.types.Operator):
|
|||||||
if props.related_topic == blender_topic.title:
|
if props.related_topic == blender_topic.title:
|
||||||
# Prevent adding self as related topic
|
# Prevent adding self as related topic
|
||||||
return False
|
return False
|
||||||
related_topic = None
|
related_topic_guid = None
|
||||||
for topic in bcfxml.topics.values():
|
for topic in bcfxml.topics.values():
|
||||||
if topic.title == props.related_topic:
|
if topic.topic.title == props.related_topic:
|
||||||
related_topic = bcf.v2.data.RelatedTopic()
|
related_topic_guid = topic.guid
|
||||||
related_topic.guid = topic.guid
|
|
||||||
break
|
break
|
||||||
if not related_topic:
|
if not related_topic_guid:
|
||||||
return False
|
return False
|
||||||
if str(related_topic.guid) in [t.name for t in blender_topic.related_topics]:
|
if str(related_topic_guid) in [t.name for t in blender_topic.related_topics]:
|
||||||
# Prevent adding the same related topic more than once
|
# Prevent adding the same related topic more than once
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
@@ -343,11 +344,12 @@ class AddBcfRelatedTopic(bpy.types.Operator):
|
|||||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
related_topic = bcf.v2.data.RelatedTopic()
|
|
||||||
related_topic.guid = next((t for t in bcfxml.topics.values() if t.title == props.related_topic)).guid
|
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
topic.related_topics.append(related_topic)
|
topic.topic.related_topic.append(
|
||||||
bcfxml.edit_topic(topic)
|
bcf.v2.model.TopicRelatedTopic(
|
||||||
|
guid=next((t for t in bcfxml.topics.values() if t.topic.title == props.related_topic)).guid
|
||||||
|
)
|
||||||
|
)
|
||||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||||
props.related_topic = ""
|
props.related_topic = ""
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -367,15 +369,24 @@ class AddBcfHeaderFile(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
header_file = bcf.v2.data.HeaderFile()
|
|
||||||
header_file.reference = props.file_reference
|
is_external = "://" in props.file_reference
|
||||||
if not os.path.exists(header_file.reference):
|
filename = Path(props.file_reference).name if os.path.exists(props.file_reference) else None
|
||||||
header_file.filename = header_file.reference
|
|
||||||
if len(props.file_ifc_project) == 22:
|
if filename:
|
||||||
header_file.ifc_project = props.file_ifc_project
|
with open(props.file_reference, "r") as f:
|
||||||
if len(props.file_ifc_spatial_structure_element) == 22:
|
topic.reference_files[filename] = f.read()
|
||||||
header_file.ifc_spatial_structure_element = props.file_ifc_spatial_structure_element
|
|
||||||
bcfxml.add_file(topic, header_file)
|
header_file = bcf.v2.model.HeaderFile(
|
||||||
|
filename=filename,
|
||||||
|
date=XmlDateTime.now(),
|
||||||
|
reference=props.file_reference if is_external else Path(props.file_reference).name,
|
||||||
|
ifc_project=props.file_ifc_project,
|
||||||
|
ifc_spatial_structure_element=props.file_ifc_spatial_structure_element,
|
||||||
|
is_external=is_external,
|
||||||
|
)
|
||||||
|
topic.header.file.append(header_file)
|
||||||
|
|
||||||
props.refresh_topic(context)
|
props.refresh_topic(context)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -409,27 +420,34 @@ class AddBcfViewpoint(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
viewpoint = bcf.v2.data.Viewpoint()
|
|
||||||
|
|
||||||
if blender_camera.data.type == "ORTHO":
|
|
||||||
camera = bcf.v2.data.OrthogonalCamera()
|
|
||||||
camera.view_to_world_scale = blender_camera.data.ortho_scale
|
|
||||||
viewpoint.orthogonal_camera = camera
|
|
||||||
elif blender_camera.data.type == "PERSP":
|
|
||||||
camera = bcf.v2.data.PerspectiveCamera()
|
|
||||||
camera.field_of_view = degrees(blender_camera.data.angle)
|
|
||||||
viewpoint.perspective_camera = camera
|
|
||||||
camera.camera_view_point.x = blender_camera.location.x
|
|
||||||
camera.camera_view_point.y = blender_camera.location.y
|
|
||||||
camera.camera_view_point.z = blender_camera.location.z
|
|
||||||
direction = blender_camera.matrix_world.to_quaternion() @ Vector((0.0, 0.0, -1.0))
|
direction = blender_camera.matrix_world.to_quaternion() @ Vector((0.0, 0.0, -1.0))
|
||||||
camera.camera_direction.x = direction.x
|
|
||||||
camera.camera_direction.y = direction.y
|
|
||||||
camera.camera_direction.z = direction.z
|
|
||||||
up = blender_camera.matrix_world.to_quaternion() @ Vector((0.0, 1.0, 0.0))
|
up = blender_camera.matrix_world.to_quaternion() @ Vector((0.0, 1.0, 0.0))
|
||||||
camera.camera_up_vector.x = up.x
|
|
||||||
camera.camera_up_vector.y = up.y
|
camera_view_point = bcf.v2.model.Point(
|
||||||
camera.camera_up_vector.z = up.z
|
x=blender_camera.location.x, y=blender_camera.location.y, z=blender_camera.location.z
|
||||||
|
)
|
||||||
|
camera_direction = bcf.v2.model.Direction(x=direction.x, y=direction.y, z=direction.z)
|
||||||
|
camera_up_vector = bcf.v2.model.Direction(x=up.x, y=up.y, z=up.z)
|
||||||
|
if blender_camera.data.type == "ORTHO":
|
||||||
|
camera = bcf.v2.model.OrthogonalCamera(
|
||||||
|
view_to_world_scale=blender_camera.data.ortho_scale,
|
||||||
|
camera_view_point=camera_view_point,
|
||||||
|
camera_direction=camera_direction,
|
||||||
|
camera_up_vector=camera_up_vector,
|
||||||
|
)
|
||||||
|
visualization_info = bcf.v2.model.VisualizationInfo(orthogonal_camera=camera)
|
||||||
|
elif blender_camera.data.type == "PERSP":
|
||||||
|
camera = bcf.v2.model.PerspectiveCamera(
|
||||||
|
field_of_view=degrees(blender_camera.data.angle),
|
||||||
|
camera_view_point=camera_view_point,
|
||||||
|
camera_direction=camera_direction,
|
||||||
|
camera_up_vector=camera_up_vector,
|
||||||
|
)
|
||||||
|
visualization_info = bcf.v2.model.VisualizationInfo(guid=str(uuid.uuid4()), perspective_camera=camera)
|
||||||
|
|
||||||
|
# TODO allow the user to enable or disable snapshotting
|
||||||
|
snapshot = None
|
||||||
|
|
||||||
blender_render = context.scene.render
|
blender_render = context.scene.render
|
||||||
old_file_format = blender_render.image_settings.file_format
|
old_file_format = blender_render.image_settings.file_format
|
||||||
@@ -437,9 +455,17 @@ class AddBcfViewpoint(bpy.types.Operator):
|
|||||||
old_filepath = blender_render.filepath
|
old_filepath = blender_render.filepath
|
||||||
blender_render.filepath = os.path.join(context.scene.BIMProperties.data_dir, "snapshot.png")
|
blender_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 = blender_render.filepath
|
with open(blender_render.filepath, "rb") as f:
|
||||||
|
snapshot = f.read()
|
||||||
|
# viewpoint.snapshot = blender_render.filepath
|
||||||
|
|
||||||
|
# TODO we should handle selection and visibility state
|
||||||
|
vizinfo = bcf.v2.visinfo.VisualizationInfoHandler(visualization_info=visualization_info, snapshot=snapshot)
|
||||||
|
topic.viewpoints[vizinfo.guid + ".bcfv"] = vizinfo
|
||||||
|
topic.markup.viewpoints.append(
|
||||||
|
bcf.v2.model.ViewPoint(viewpoint=vizinfo.guid + ".bcfv", guid=vizinfo.guid, snapshot=vizinfo.guid + ".png")
|
||||||
|
)
|
||||||
|
|
||||||
bcfxml.add_viewpoint(topic, viewpoint)
|
|
||||||
blender_render.filepath = old_filepath
|
blender_render.filepath = old_filepath
|
||||||
blender_render.image_settings.file_format = old_file_format
|
blender_render.image_settings.file_format = old_file_format
|
||||||
props.refresh_topic(context)
|
props.refresh_topic(context)
|
||||||
@@ -459,9 +485,15 @@ class RemoveBcfViewpoint(bpy.types.Operator):
|
|||||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
viewpoint_guid = blender_topic.viewpoints
|
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
bcfxml.delete_viewpoint(viewpoint_guid, topic)
|
for key, viewpoint in topic.viewpoints.items():
|
||||||
|
if viewpoint.guid == blender_topic.viewpoints:
|
||||||
|
break
|
||||||
|
del topic.viewpoints[key]
|
||||||
|
for i, viewpoint in enumerate(topic.markup.viewpoints):
|
||||||
|
if viewpoint.guid == blender_topic.viewpoints:
|
||||||
|
break
|
||||||
|
del topic.markup.viewpoints[i]
|
||||||
props.refresh_topic(context)
|
props.refresh_topic(context)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -477,7 +509,7 @@ class RemoveBcfFile(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
bcfxml.delete_file(topic, self.index)
|
del topic.header.file[self.index]
|
||||||
props.refresh_topic(context)
|
props.refresh_topic(context)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -495,8 +527,7 @@ class RemoveBcfTopic(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
topic_to_delete = props.active_topic
|
del bcfxml.topics[props.active_topic.name]
|
||||||
bcfxml.delete_topic(topic_to_delete.name)
|
|
||||||
bpy.ops.bim.load_bcf_topics()
|
bpy.ops.bim.load_bcf_topics()
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -515,8 +546,7 @@ class AddBcfReferenceLink(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
topic.reference_links.append(props.reference_link)
|
topic.topic.reference_link.append(props.reference_link)
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||||
props.reference_link = ""
|
props.reference_link = ""
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -536,10 +566,23 @@ class AddBcfDocumentReference(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
document_reference = bcf.v2.data.DocumentReference()
|
|
||||||
document_reference.referenced_document = props.document_reference
|
is_external = "://" in props.document_reference
|
||||||
document_reference.description = props.document_reference_description or None
|
filename = Path(props.document_reference).name if os.path.exists(props.document_reference) else None
|
||||||
bcfxml.add_document_reference(topic, document_reference)
|
|
||||||
|
if filename:
|
||||||
|
with open(props.document_reference, "rb") as f:
|
||||||
|
topic.document_references[filename] = f.read()
|
||||||
|
|
||||||
|
document_reference = bcf.v2.model.TopicDocumentReference(
|
||||||
|
referenced_document=props.document_reference if is_external else filename,
|
||||||
|
description=props.document_reference_description or None,
|
||||||
|
guid=str(uuid.uuid4()),
|
||||||
|
is_external=is_external,
|
||||||
|
)
|
||||||
|
|
||||||
|
topic.topic.document_reference.append(document_reference)
|
||||||
|
|
||||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||||
props.document_reference = ""
|
props.document_reference = ""
|
||||||
props.document_reference_description = ""
|
props.document_reference_description = ""
|
||||||
@@ -562,8 +605,7 @@ class AddBcfLabel(bpy.types.Operator):
|
|||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
new = blender_topic.labels.add()
|
new = blender_topic.labels.add()
|
||||||
new.name = props.label
|
new.name = props.label
|
||||||
topic.labels.append(props.label)
|
topic.topic.labels.append(props.label)
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
props.label = ""
|
props.label = ""
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -578,11 +620,10 @@ class EditBcfReferenceLinks(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
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.topic.reference_link):
|
||||||
if reference_link == blender_topic.reference_links[index].name:
|
if reference_link == blender_topic.reference_links[index].name:
|
||||||
continue
|
continue
|
||||||
topic.reference_links[index] = blender_topic.reference_links[index].name
|
topic.topic.reference_link[index] = blender_topic.reference_links[index].name
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -597,12 +638,11 @@ class EditBcfLabels(bpy.types.Operator):
|
|||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
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):
|
||||||
if index >= len(topic.labels):
|
if index >= len(topic.topic.labels):
|
||||||
break
|
break
|
||||||
if label.name == topic.labels[index]:
|
if label.name == topic.topic.labels[index]:
|
||||||
continue
|
continue
|
||||||
topic.labels[index] = blender_topic.labels[index].name
|
topic.topic.labels[index] = blender_topic.labels[index].name
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -617,8 +657,7 @@ class RemoveBcfReferenceLink(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
del topic.reference_links[self.index]
|
del topic.topic.reference_link[self.index]
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
blender_topic.reference_links.remove(self.index)
|
blender_topic.reference_links.remove(self.index)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -634,8 +673,7 @@ class RemoveBcfLabel(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
del topic.labels[self.index]
|
del topic.topic.labels[self.index]
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
blender_topic.labels.remove(self.index)
|
blender_topic.labels.remove(self.index)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -650,7 +688,7 @@ class RemoveBcfBimSnippet(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
bcfxml.delete_bim_snippet(topic)
|
topic.topic.bim_snippet = None
|
||||||
blender_topic.bim_snippet.schema = ""
|
blender_topic.bim_snippet.schema = ""
|
||||||
blender_topic.bim_snippet.reference = ""
|
blender_topic.bim_snippet.reference = ""
|
||||||
blender_topic.bim_snippet.type = ""
|
blender_topic.bim_snippet.type = ""
|
||||||
@@ -668,7 +706,7 @@ class RemoveBcfDocumentReference(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
bcfxml.delete_document_reference(topic, self.index)
|
del topic.topic.document_reference[self.index]
|
||||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -684,8 +722,7 @@ class RemoveBcfRelatedTopic(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
del topic.related_topics[self.index]
|
del topic.topic.related_topic[self.index]
|
||||||
bcfxml.edit_topic(topic)
|
|
||||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -701,7 +738,10 @@ class RemoveBcfComment(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
bcfxml.delete_comment(self.comment_guid, topic)
|
for i, comment in enumerate(topic.comments):
|
||||||
|
if comment.guid == self.comment_guid:
|
||||||
|
break
|
||||||
|
del topic.comments[i]
|
||||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -718,9 +758,11 @@ class EditBcfComment(bpy.types.Operator):
|
|||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
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]
|
||||||
comment = topic.comments[self.comment_guid]
|
for i, comment in enumerate(topic.comments):
|
||||||
comment.comment = blender_comment.comment
|
if comment.guid == self.comment_guid:
|
||||||
bcfxml.edit_comment(comment, topic)
|
comment.comment = blender_comment.comment
|
||||||
|
comment.modified_date = XmlDateTime.now()
|
||||||
|
comment.modified_author = context.scene.BCFProperties.author
|
||||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -745,12 +787,15 @@ class AddBcfComment(bpy.types.Operator):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
blender_topic = props.active_topic
|
blender_topic = props.active_topic
|
||||||
topic = bcfxml.topics[blender_topic.name]
|
topic = bcfxml.topics[blender_topic.name]
|
||||||
comment = bcf.v2.data.Comment()
|
comment = bcf.v2.model.Comment(
|
||||||
comment.comment = props.comment
|
date=XmlDateTime.now(),
|
||||||
|
author=context.scene.BCFProperties.author,
|
||||||
|
comment=props.comment,
|
||||||
|
guid=str(uuid.uuid4()),
|
||||||
|
)
|
||||||
if props.has_related_viewpoint:
|
if props.has_related_viewpoint:
|
||||||
comment.viewpoint = bcf.v2.data.Viewpoint()
|
comment.viewpoint = bcf.v2.model.CommentViewpoint(guid=blender_topic.viewpoints)
|
||||||
comment.viewpoint.guid = blender_topic.viewpoints
|
topic.comments.append(comment)
|
||||||
bcfxml.add_comment(topic, comment)
|
|
||||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||||
props.comment = ""
|
props.comment = ""
|
||||||
props.has_related_viewpoint = False
|
props.has_related_viewpoint = False
|
||||||
@@ -791,11 +836,13 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
cam_height = context.scene.render.resolution_y
|
cam_height = context.scene.render.resolution_y
|
||||||
cam_aspect = cam_width / cam_height
|
cam_aspect = cam_width / cam_height
|
||||||
|
|
||||||
|
obj.data.background_images.clear()
|
||||||
if viewpoint.snapshot:
|
if viewpoint.snapshot:
|
||||||
obj.data.show_background_images = True
|
obj.data.show_background_images = True
|
||||||
obj.data.background_images.clear()
|
|
||||||
background = obj.data.background_images.new()
|
background = obj.data.background_images.new()
|
||||||
background.image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, viewpoint.snapshot))
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||||
|
f.write(viewpoint.snapshot)
|
||||||
|
background.image = bpy.data.images.load(f.name)
|
||||||
src_width = background.image.size[0]
|
src_width = background.image.size[0]
|
||||||
src_height = background.image.size[1]
|
src_height = background.image.size[1]
|
||||||
src_aspect = src_width / src_height
|
src_aspect = src_width / src_height
|
||||||
@@ -805,6 +852,9 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
else:
|
else:
|
||||||
background.frame_method = "CROP"
|
background.frame_method = "CROP"
|
||||||
background.display_depth = "FRONT"
|
background.display_depth = "FRONT"
|
||||||
|
else:
|
||||||
|
obj.data.show_background_images = False
|
||||||
|
|
||||||
area = next(area for area in 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"
|
||||||
|
|
||||||
@@ -814,27 +864,27 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
gp = bpy.data.grease_pencils.get("BCF")
|
gp = bpy.data.grease_pencils.get("BCF")
|
||||||
if gp:
|
if gp:
|
||||||
bpy.data.grease_pencils.remove(gp)
|
bpy.data.grease_pencils.remove(gp)
|
||||||
if viewpoint.lines:
|
if viewpoint.visualization_info.lines:
|
||||||
self.draw_lines(viewpoint, context)
|
self.draw_lines(viewpoint, context)
|
||||||
|
|
||||||
self.delete_clipping_planes(context)
|
self.delete_clipping_planes(context)
|
||||||
if viewpoint.clipping_planes:
|
if viewpoint.visualization_info.clipping_planes:
|
||||||
self.create_clipping_planes(viewpoint)
|
self.create_clipping_planes(viewpoint)
|
||||||
|
|
||||||
self.delete_bitmaps(context)
|
self.delete_bitmaps(context)
|
||||||
if viewpoint.bitmaps:
|
if viewpoint.visualization_info.bitmap:
|
||||||
self.create_bitmaps(bcfxml, viewpoint, topic)
|
self.create_bitmaps(bcfxml, viewpoint, topic)
|
||||||
|
|
||||||
self.setup_camera(viewpoint, obj, cam_aspect, context)
|
self.setup_camera(viewpoint, obj, cam_aspect, context)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def setup_camera(self, viewpoint, obj, cam_aspect, context):
|
def setup_camera(self, viewpoint, obj, cam_aspect, context):
|
||||||
if viewpoint.orthogonal_camera:
|
if viewpoint.visualization_info.orthogonal_camera:
|
||||||
camera = viewpoint.orthogonal_camera
|
camera = viewpoint.visualization_info.orthogonal_camera
|
||||||
obj.data.type = "ORTHO"
|
obj.data.type = "ORTHO"
|
||||||
obj.data.ortho_scale = viewpoint.orthogonal_camera.view_to_world_scale
|
obj.data.ortho_scale = viewpoint.visualization_info.orthogonal_camera.view_to_world_scale
|
||||||
elif viewpoint.perspective_camera:
|
elif viewpoint.visualization_info.perspective_camera:
|
||||||
camera = viewpoint.perspective_camera
|
camera = viewpoint.visualization_info.perspective_camera
|
||||||
obj.data.type = "PERSP"
|
obj.data.type = "PERSP"
|
||||||
if cam_aspect >= 1:
|
if cam_aspect >= 1:
|
||||||
obj.data.angle = radians(camera.field_of_view)
|
obj.data.angle = radians(camera.field_of_view)
|
||||||
@@ -875,15 +925,15 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
obj.matrix_world = Matrix(matrix.tolist())
|
obj.matrix_world = Matrix(matrix.tolist())
|
||||||
|
|
||||||
def set_viewpoint_components(self, viewpoint, context):
|
def set_viewpoint_components(self, viewpoint, context):
|
||||||
if not viewpoint.components:
|
if not viewpoint.visualization_info.components:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Operators with context overrides are used because they are
|
# Operators with context overrides are used because they are
|
||||||
# significantly faster than looping through all objects
|
# significantly faster than looping through all objects
|
||||||
|
|
||||||
exception_global_ids = {v.ifc_guid for v in viewpoint.components.visibility.exceptions}
|
exception_global_ids = {v.ifc_guid for v in viewpoint.visualization_info.components.visibility.exceptions}
|
||||||
|
|
||||||
if viewpoint.components.visibility.default_visibility:
|
if viewpoint.visualization_info.components.visibility.default_visibility:
|
||||||
old = context.area.type
|
old = context.area.type
|
||||||
context.area.type = "VIEW_3D"
|
context.area.type = "VIEW_3D"
|
||||||
bpy.ops.object.hide_view_clear()
|
bpy.ops.object.hide_view_clear()
|
||||||
@@ -907,11 +957,13 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
bpy.ops.object.hide_view_set(context_override, unselected=True)
|
bpy.ops.object.hide_view_set(context_override, unselected=True)
|
||||||
context.area.type = old
|
context.area.type = old
|
||||||
|
|
||||||
if viewpoint.components.view_setup_hints:
|
if viewpoint.visualization_info.components.view_setup_hints:
|
||||||
if not viewpoint.components.view_setup_hints.spaces_visible:
|
if not viewpoint.visualization_info.components.view_setup_hints.spaces_visible:
|
||||||
self.hide_spaces(context)
|
self.hide_spaces(context)
|
||||||
if viewpoint.components.view_setup_hints.openings_visible is not None:
|
if viewpoint.visualization_info.components.view_setup_hints.openings_visible is not None:
|
||||||
self.set_openings_visibility(viewpoint.components.view_setup_hints.openings_visible, context)
|
self.set_openings_visibility(
|
||||||
|
viewpoint.visualization_info.components.view_setup_hints.openings_visible, context
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.hide_spaces(context)
|
self.hide_spaces(context)
|
||||||
self.set_openings_visibility(False, context)
|
self.set_openings_visibility(False, context)
|
||||||
@@ -931,7 +983,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
collection.hide_viewport = not is_visible
|
collection.hide_viewport = not is_visible
|
||||||
|
|
||||||
def set_selection(self, viewpoint):
|
def set_selection(self, viewpoint):
|
||||||
selected_global_ids = [s.ifc_guid for s in viewpoint.components.selection]
|
selected_global_ids = [s.ifc_guid for s in viewpoint.visualization_info.components.selection]
|
||||||
bpy.ops.object.select_all(action="DESELECT")
|
bpy.ops.object.select_all(action="DESELECT")
|
||||||
for global_id in selected_global_ids:
|
for global_id in selected_global_ids:
|
||||||
obj = IfcStore.get_element(global_id)
|
obj = IfcStore.get_element(global_id)
|
||||||
@@ -940,7 +992,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
|
|
||||||
def set_colours(self, viewpoint):
|
def set_colours(self, viewpoint):
|
||||||
global_id_colours = {}
|
global_id_colours = {}
|
||||||
for coloring in viewpoint.components.coloring:
|
for coloring in viewpoint.visualization_info.components.coloring:
|
||||||
for component in coloring.components:
|
for component in coloring.components:
|
||||||
global_id_colours.setdefault(component.ifc_guid, coloring.color)
|
global_id_colours.setdefault(component.ifc_guid, coloring.color)
|
||||||
for global_id, color in global_id_colours.items():
|
for global_id, color in global_id_colours.items():
|
||||||
@@ -967,9 +1019,9 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
frame = layer.frames.new(1)
|
frame = layer.frames.new(1)
|
||||||
stroke = frame.strokes.new()
|
stroke = frame.strokes.new()
|
||||||
stroke.display_mode = "3DSPACE"
|
stroke.display_mode = "3DSPACE"
|
||||||
stroke.points.add(len(viewpoint.lines) * 2)
|
stroke.points.add(len(viewpoint.visualization_info.lines.line) * 2)
|
||||||
coords = []
|
coords = []
|
||||||
for l in viewpoint.lines:
|
for l in viewpoint.visualization_info.lines.line:
|
||||||
coords.extend(
|
coords.extend(
|
||||||
[l.start_point.x, l.start_point.y, l.start_point.z, l.end_point.x, l.end_point.y, l.end_point.z]
|
[l.start_point.x, l.start_point.y, l.start_point.z, l.end_point.x, l.end_point.y, l.end_point.z]
|
||||||
)
|
)
|
||||||
@@ -977,7 +1029,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
|
|
||||||
def create_clipping_planes(self, viewpoint):
|
def create_clipping_planes(self, viewpoint):
|
||||||
n = 0
|
n = 0
|
||||||
for plane in viewpoint.clipping_planes:
|
for plane in viewpoint.visualization_info.clipping_planes.clipping_plane:
|
||||||
bpy.ops.bim.add_section_plane()
|
bpy.ops.bim.add_section_plane()
|
||||||
if n == 0:
|
if n == 0:
|
||||||
obj = bpy.data.objects["Section"]
|
obj = bpy.data.objects["Section"]
|
||||||
@@ -1010,10 +1062,14 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
|||||||
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")
|
||||||
for bitmap in viewpoint.bitmaps:
|
for bitmap in viewpoint.visualization_info.bitmap:
|
||||||
obj = bpy.data.objects.new("Bitmap", None)
|
obj = bpy.data.objects.new("Bitmap", None)
|
||||||
obj.empty_display_type = "IMAGE"
|
obj.empty_display_type = "IMAGE"
|
||||||
image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, bitmap.reference))
|
# image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, bitmap.reference))
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||||
|
topic.extract_file(bitmap, f.name)
|
||||||
|
# f.write(bitmap.what)
|
||||||
|
image = bpy.data.images.load(f.name)
|
||||||
src_width = image.size[0]
|
src_width = image.size[0]
|
||||||
src_height = image.size[1]
|
src_height = image.size[1]
|
||||||
if src_height > src_width:
|
if src_height > src_width:
|
||||||
@@ -1052,6 +1108,7 @@ class SelectBcfHeaderFile(bpy.types.Operator):
|
|||||||
bl_label = "Select BCF Header File"
|
bl_label = "Select BCF Header File"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||||
|
filter_glob: bpy.props.StringProperty(default="*.ifc;*.ifczip;*.ifcxml;*.ifcjson", options={"HIDDEN"})
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
if self.filepath:
|
if self.filepath:
|
||||||
@@ -1093,3 +1150,25 @@ class SelectBcfDocumentReference(bpy.types.Operator):
|
|||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
context.window_manager.fileselect_add(self)
|
context.window_manager.fileselect_add(self)
|
||||||
return {"RUNNING_MODAL"}
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
|
|
||||||
|
class ExtractBcfFile(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.extract_bcf_file"
|
||||||
|
bl_label = "Extract BCF Header File"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
entity_type: bpy.props.StringProperty()
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||||
|
topic = bcfxml.topics[context.scene.BCFProperties.active_topic.name]
|
||||||
|
|
||||||
|
if self.entity_type == "HEADER_FILE":
|
||||||
|
entity = topic.header.file[self.index]
|
||||||
|
elif self.entity_type == "BIM_SNIPPET":
|
||||||
|
entity = topic.markup.topic.bim_snippet
|
||||||
|
elif self.entity_type == "DOCUMENT_REFERENCE":
|
||||||
|
entity = topic.markup.topic.document_reference[self.index]
|
||||||
|
|
||||||
|
webbrowser.open(str(topic.extract_file(entity).parent))
|
||||||
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -95,8 +95,8 @@ def getBcfViewpoints(self, context, force_update=False):
|
|||||||
props = context.scene.BCFProperties
|
props = context.scene.BCFProperties
|
||||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||||
topic = props.active_topic
|
topic = props.active_topic
|
||||||
viewpoints = bcfxml.get_viewpoints(topic.name) if topic else {}
|
viewpoints = bcfxml.topics[topic.name].viewpoints.keys() if topic else []
|
||||||
bcfviewpoints_enum.extend([(v, f"Viewpoint {i+1}", "") for i, v in enumerate(viewpoints.keys())])
|
bcfviewpoints_enum.extend([(v, f"Viewpoint {i+1}", "") for i, v in enumerate(viewpoints)])
|
||||||
return bcfviewpoints_enum
|
return bcfviewpoints_enum
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -127,20 +127,21 @@ class BIM_PT_bcf_metadata(Panel):
|
|||||||
layout.label(text="Header Files:")
|
layout.label(text="Header Files:")
|
||||||
|
|
||||||
if bcf_topic.header:
|
if bcf_topic.header:
|
||||||
for index, f in enumerate(bcf_topic.header.files):
|
for index, f in enumerate(bcf_topic.header.file):
|
||||||
box = self.layout.box()
|
box = self.layout.box()
|
||||||
row = box.row(align=True)
|
row = box.row(align=True)
|
||||||
row.label(text=f.filename, icon="FILE_BLANK")
|
row.label(text=f.filename, icon="FILE_BLANK")
|
||||||
if f.is_external:
|
if f.is_external:
|
||||||
row.operator("bim.open_uri", icon="URL", text="").uri = f.reference
|
row.operator("bim.open_uri", icon="URL", text="").uri = f.reference
|
||||||
else:
|
else:
|
||||||
op = row.operator("bim.open_uri", icon="FILE_FOLDER", text="")
|
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
||||||
op.uri = os.path.join(bcfxml.filepath, topic.name, f.reference)
|
op.index = index
|
||||||
|
op.entity_type = "HEADER_FILE"
|
||||||
row.operator("bim.remove_bcf_file", icon="X", text="").index = index
|
row.operator("bim.remove_bcf_file", icon="X", text="").index = index
|
||||||
|
|
||||||
row = box.row()
|
row = box.row()
|
||||||
row.label(text="Date")
|
row.label(text="Date")
|
||||||
row.label(text=f.date)
|
row.label(text=str(f.date))
|
||||||
|
|
||||||
if f.ifc_project:
|
if f.ifc_project:
|
||||||
row = box.row()
|
row = box.row()
|
||||||
@@ -196,8 +197,8 @@ class BIM_PT_bcf_metadata(Panel):
|
|||||||
if topic.bim_snippet.is_external:
|
if topic.bim_snippet.is_external:
|
||||||
row.operator("bim.open_uri", icon="URL", text="").uri = topic.bim_snippet.reference
|
row.operator("bim.open_uri", icon="URL", text="").uri = topic.bim_snippet.reference
|
||||||
else:
|
else:
|
||||||
op = row.operator("bim.open_uri", icon="FILE_FOLDER", text="")
|
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
||||||
op.uri = os.path.join(bcfxml.filepath, topic.name, topic.bim_snippet.reference)
|
op.entity_type = "BIM_SNIPPET"
|
||||||
row.operator("bim.remove_bcf_bim_snippet", icon="X", text="")
|
row.operator("bim.remove_bcf_bim_snippet", icon="X", text="")
|
||||||
else:
|
else:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
@@ -218,8 +219,10 @@ class BIM_PT_bcf_metadata(Panel):
|
|||||||
if doc.is_external:
|
if doc.is_external:
|
||||||
row.operator("bim.open_uri", icon="URL", text="").uri = doc.reference
|
row.operator("bim.open_uri", icon="URL", text="").uri = doc.reference
|
||||||
else:
|
else:
|
||||||
op = row.operator("bim.open_uri", icon="FILE_FOLDER", text="")
|
op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="")
|
||||||
op.uri = os.path.join(bcfxml.filepath, topic.name, doc.reference)
|
op.entity_type = "DOCUMENT_REFERENCE"
|
||||||
|
op.index = index
|
||||||
|
|
||||||
row.operator("bim.remove_bcf_document_reference", icon="X", text="").index = index
|
row.operator("bim.remove_bcf_document_reference", icon="X", text="").index = index
|
||||||
row = box.row(align=True)
|
row = box.row(align=True)
|
||||||
row.prop(doc, "description")
|
row.prop(doc, "description")
|
||||||
@@ -236,7 +239,7 @@ class BIM_PT_bcf_metadata(Panel):
|
|||||||
try:
|
try:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
op = row.operator(
|
op = row.operator(
|
||||||
"bim.view_bcf_topic", text=f"Select {bcfxml.topics[related_topic.name.lower()].title}"
|
"bim.view_bcf_topic", text=f"Select {bcfxml.topics[related_topic.name.lower()].topic.title}"
|
||||||
)
|
)
|
||||||
op.topic_guid = related_topic.name
|
op.topic_guid = related_topic.name
|
||||||
row.operator("bim.remove_bcf_related_topic", icon="X", text="").index = index
|
row.operator("bim.remove_bcf_related_topic", icon="X", text="").index = index
|
||||||
|
|||||||
Reference in New Issue
Block a user