Reference images attached to the drawings #3447

You can also save them as annotation types.
Example - https://imgur.com/a/6trT7SZ
This commit is contained in:
Andrej730
2023-12-01 16:16:04 +05:00
parent e53c0b74b1
commit da306c6141
4 changed files with 68 additions and 21 deletions
@@ -104,6 +104,9 @@ class AddAnnotationType(bpy.types.Operator, Operator):
) )
element.ApplicableOccurrence = f"IfcAnnotation/{object_type}" element.ApplicableOccurrence = f"IfcAnnotation/{object_type}"
if props.create_representation_for_type and object_type == "IMAGE":
bpy.ops.bim.add_reference_image("INVOKE_DEFAULT", use_existing_object_by_name=obj.name)
class EnableAddAnnotationType(bpy.types.Operator, Operator): class EnableAddAnnotationType(bpy.types.Operator, Operator):
bl_idname = "bim.enable_add_annotation_type" bl_idname = "bim.enable_add_annotation_type"
@@ -2581,6 +2584,11 @@ class AddReferenceImage(bpy.types.Operator, Operator):
"Override image if it was previously loaded to Blender. If disabled, will always create a new image" "Override image if it was previously loaded to Blender. If disabled, will always create a new image"
), ),
) )
use_existing_object_by_name: bpy.props.StringProperty(
name="Use Existing Object By Name",
description="Existing object name to add a style with reference image to. If not provided will create a new object.",
options={"SKIP_SAVE"},
)
def invoke(self, context, event): def invoke(self, context, event):
context.window_manager.fileselect_add(self) context.window_manager.fileselect_add(self)
@@ -2596,29 +2604,33 @@ class AddReferenceImage(bpy.types.Operator, Operator):
params = {"check_existing": False} params = {"check_existing": False}
image = load_image(image_filepath.name, image_filepath.parent, **params) image = load_image(image_filepath.name, image_filepath.parent, **params)
temp_mesh = bpy.data.meshes.new("temp_mesh") def bm_add_image_plane(mesh):
bm = tool.Blender.get_bmesh_for_mesh(temp_mesh) bm = tool.Blender.get_bmesh_for_mesh(mesh, clean=True)
plane_scale = (Vector(image.size) / min(image.size)).to_3d() plane_scale = (Vector(image.size) / min(image.size)).to_3d()
matrix = Matrix.LocRotScale(None, None, plane_scale) matrix = Matrix.LocRotScale(None, None, plane_scale)
bmesh.ops.create_grid(bm, x_segments=1, y_segments=1, size=1, matrix=matrix, calc_uvs=False) bmesh.ops.create_grid(bm, x_segments=1, y_segments=1, size=1, matrix=matrix, calc_uvs=False)
tool.Blender.apply_bmesh(temp_mesh, bm) tool.Blender.apply_bmesh(mesh, bm)
obj = bpy.data.objects.new(image_filepath.stem, temp_mesh)
# assign to the active collection if self.use_existing_object_by_name:
collection = context.view_layer.active_layer_collection.collection obj = bpy.data.objects[self.use_existing_object_by_name]
collection.objects.link(obj) bm_add_image_plane(obj.data)
bpy.ops.bim.update_representation(obj=obj.name, ifc_representation_class="")
tool.Drawing.run_root_assign_class( else:
obj=obj, temp_mesh = bpy.data.meshes.new("temp_mesh")
ifc_class="IfcAnnotation", bm_add_image_plane(temp_mesh)
predefined_type="IMAGE", obj = bpy.data.objects.new(image_filepath.stem, temp_mesh)
should_add_representation=True, tool.Drawing.run_root_assign_class(
context=ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW"), obj=obj,
ifc_representation_class=None, ifc_class="IfcAnnotation",
) predefined_type="IMAGE",
tool.Blender.remove_data_block(temp_mesh) should_add_representation=True,
context=ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW"),
ifc_representation_class=None,
)
tool.Blender.remove_data_block(temp_mesh)
tool.Blender.set_active_object(obj) tool.Blender.set_active_object(obj)
material = bpy.data.materials.new(name=image_filepath.stem) material = bpy.data.materials.new(name=image_filepath.stem)
obj.data.materials.append(None) # new slot obj.data.materials.append(None) # new slot
obj.material_slots[0].material = material obj.material_slots[0].material = material
@@ -2626,8 +2638,8 @@ class AddReferenceImage(bpy.types.Operator, Operator):
style = ifc_file.by_id(material.BIMMaterialProperties.ifc_style_id) style = ifc_file.by_id(material.BIMMaterialProperties.ifc_style_id)
tool.Style.assign_style_to_object(style, obj) tool.Style.assign_style_to_object(style, obj)
tool.Geometry.record_object_materials(obj)
material.diffuse_color = (0.031379, 0, 0.801157, 1)
material.BIMStyleProperties.diffuse_path = self.filepath material.BIMStyleProperties.diffuse_path = self.filepath
material.BIMStyleProperties.uv_mode = "Generated" material.BIMStyleProperties.uv_mode = "Generated"
bpy.ops.bim.update_style_colours() bpy.ops.bim.update_style_colours()
@@ -515,6 +515,7 @@ ANNOTATION_TYPES_DATA = {
"REVISION_CLOUD":("Revision Cloud", "Add revision cloud", "VOLUME_DATA", "mesh"), "REVISION_CLOUD":("Revision Cloud", "Add revision cloud", "VOLUME_DATA", "mesh"),
"FILL_AREA": ("Fill Area", "", "NODE_TEXTURE", "mesh"), "FILL_AREA": ("Fill Area", "", "NODE_TEXTURE", "mesh"),
"FALL": ("Fall", "", "SORT_ASC", "curve"), "FALL": ("Fall", "", "SORT_ASC", "curve"),
"IMAGE": ("Image", "Add reference image attached to the drawing", "TEXTURE", "mesh"),
} }
# fmt: on # fmt: on
@@ -186,6 +186,9 @@ def create_annotation_occurrence(context):
tool.Collector.assign(obj) tool.Collector.assign(obj)
tool.Blender.select_and_activate_single_object(context, obj) tool.Blender.select_and_activate_single_object(context, obj)
if relating_type_repr is None and props.object_type == "IMAGE":
bpy.ops.bim.add_reference_image("INVOKE_DEFAULT", use_existing_object_by_name=obj.name)
def create_annotation(): def create_annotation():
props = bpy.context.scene.BIMAnnotationProperties props = bpy.context.scene.BIMAnnotationProperties
@@ -194,6 +197,10 @@ def create_annotation():
else: else:
object_type = props.object_type object_type = props.object_type
bpy.ops.bim.add_annotation(object_type=object_type, data_type=ANNOTATION_TYPES_DATA[object_type][-1]) bpy.ops.bim.add_annotation(object_type=object_type, data_type=ANNOTATION_TYPES_DATA[object_type][-1])
if props.object_type == "IMAGE":
bpy.ops.bim.add_reference_image(
"INVOKE_DEFAULT", use_existing_object_by_name=bpy.context.active_object.name
)
class AnnotationToolUI: class AnnotationToolUI:
+27
View File
@@ -27,6 +27,7 @@ from test.bim.bootstrap import NewFile
from blenderbim.tool.drawing import Drawing as subject from blenderbim.tool.drawing import Drawing as subject
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.drawing.data import DecoratorData from blenderbim.bim.module.drawing.data import DecoratorData
from mathutils import Vector
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
@@ -847,3 +848,29 @@ class TestDrawingStyles(NewFile):
self.setup_project_with_drawing() self.setup_project_with_drawing()
bpy.ops.bim.reload_drawing_styles() bpy.ops.bim.reload_drawing_styles()
assert len(self.drawing_styles) == 3 assert len(self.drawing_styles) == 3
class TestAddReferenceImage(NewFile):
def test_run(self):
bpy.context.scene.BIMProjectProperties.template_file = "0"
bpy.ops.bim.create_project()
ifc_file = tool.Ifc.get()
filepath = Path("test/files/image.jpg").absolute()
bpy.ops.bim.add_reference_image(filepath=str(filepath))
obj = bpy.data.objects["IfcAnnotation/image"]
assert obj is not None
assert tool.Cad.are_vectors_equal(obj.dimensions, Vector((3.53982, 2.0, 0.0)))
material = obj.active_material
assert material.name == "image"
assert material.BIMMaterialProperties.ifc_style_id != 0
style = ifc_file.by_id(material.BIMMaterialProperties.ifc_style_id)
styled_items = set(tool.Style.get_styled_items(style))
representation_items = set(tool.Geometry.get_active_representation(obj).Items)
assert styled_items == representation_items
assert Path(material.BIMStyleProperties.diffuse_path) == filepath
assert material.BIMStyleProperties.uv_mode == "Generated"