mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
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:
@@ -104,6 +104,9 @@ class AddAnnotationType(bpy.types.Operator, Operator):
|
||||
)
|
||||
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):
|
||||
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"
|
||||
),
|
||||
)
|
||||
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):
|
||||
context.window_manager.fileselect_add(self)
|
||||
@@ -2596,29 +2604,33 @@ class AddReferenceImage(bpy.types.Operator, Operator):
|
||||
params = {"check_existing": False}
|
||||
image = load_image(image_filepath.name, image_filepath.parent, **params)
|
||||
|
||||
temp_mesh = bpy.data.meshes.new("temp_mesh")
|
||||
bm = tool.Blender.get_bmesh_for_mesh(temp_mesh)
|
||||
plane_scale = (Vector(image.size) / min(image.size)).to_3d()
|
||||
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)
|
||||
tool.Blender.apply_bmesh(temp_mesh, bm)
|
||||
obj = bpy.data.objects.new(image_filepath.stem, temp_mesh)
|
||||
def bm_add_image_plane(mesh):
|
||||
bm = tool.Blender.get_bmesh_for_mesh(mesh, clean=True)
|
||||
plane_scale = (Vector(image.size) / min(image.size)).to_3d()
|
||||
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)
|
||||
tool.Blender.apply_bmesh(mesh, bm)
|
||||
|
||||
# assign to the active collection
|
||||
collection = context.view_layer.active_layer_collection.collection
|
||||
collection.objects.link(obj)
|
||||
|
||||
tool.Drawing.run_root_assign_class(
|
||||
obj=obj,
|
||||
ifc_class="IfcAnnotation",
|
||||
predefined_type="IMAGE",
|
||||
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)
|
||||
if self.use_existing_object_by_name:
|
||||
obj = bpy.data.objects[self.use_existing_object_by_name]
|
||||
bm_add_image_plane(obj.data)
|
||||
bpy.ops.bim.update_representation(obj=obj.name, ifc_representation_class="")
|
||||
else:
|
||||
temp_mesh = bpy.data.meshes.new("temp_mesh")
|
||||
bm_add_image_plane(temp_mesh)
|
||||
obj = bpy.data.objects.new(image_filepath.stem, temp_mesh)
|
||||
tool.Drawing.run_root_assign_class(
|
||||
obj=obj,
|
||||
ifc_class="IfcAnnotation",
|
||||
predefined_type="IMAGE",
|
||||
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)
|
||||
|
||||
material = bpy.data.materials.new(name=image_filepath.stem)
|
||||
obj.data.materials.append(None) # new slot
|
||||
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)
|
||||
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.uv_mode = "Generated"
|
||||
bpy.ops.bim.update_style_colours()
|
||||
|
||||
@@ -515,6 +515,7 @@ ANNOTATION_TYPES_DATA = {
|
||||
"REVISION_CLOUD":("Revision Cloud", "Add revision cloud", "VOLUME_DATA", "mesh"),
|
||||
"FILL_AREA": ("Fill Area", "", "NODE_TEXTURE", "mesh"),
|
||||
"FALL": ("Fall", "", "SORT_ASC", "curve"),
|
||||
"IMAGE": ("Image", "Add reference image attached to the drawing", "TEXTURE", "mesh"),
|
||||
}
|
||||
# fmt: on
|
||||
|
||||
|
||||
@@ -186,6 +186,9 @@ def create_annotation_occurrence(context):
|
||||
tool.Collector.assign(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():
|
||||
props = bpy.context.scene.BIMAnnotationProperties
|
||||
@@ -194,6 +197,10 @@ def create_annotation():
|
||||
else:
|
||||
object_type = props.object_type
|
||||
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:
|
||||
|
||||
@@ -27,6 +27,7 @@ from test.bim.bootstrap import NewFile
|
||||
from blenderbim.tool.drawing import Drawing as subject
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.drawing.data import DecoratorData
|
||||
from mathutils import Vector
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
@@ -847,3 +848,29 @@ class TestDrawingStyles(NewFile):
|
||||
self.setup_project_with_drawing()
|
||||
bpy.ops.bim.reload_drawing_styles()
|
||||
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"
|
||||
|
||||
Reference in New Issue
Block a user