mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-08 05:16:25 +00:00
Add description to Image Scaling Tool operator for clarity + black
This commit is contained in:
@@ -895,38 +895,39 @@ class IfcImporter:
|
|||||||
material = obj.data.materials[0]
|
material = obj.data.materials[0]
|
||||||
if material.use_nodes and material.node_tree:
|
if material.use_nodes and material.node_tree:
|
||||||
for node in material.node_tree.nodes:
|
for node in material.node_tree.nodes:
|
||||||
if node.type == 'TEX_IMAGE' and node.image:
|
if node.type == "TEX_IMAGE" and node.image:
|
||||||
image = node.image
|
image = node.image
|
||||||
break
|
break
|
||||||
if image:
|
if image:
|
||||||
import bmesh
|
import bmesh
|
||||||
|
|
||||||
bm = bmesh.new()
|
bm = bmesh.new()
|
||||||
bm.from_mesh(obj.data)
|
bm.from_mesh(obj.data)
|
||||||
if not bm.loops.layers.uv:
|
if not bm.loops.layers.uv:
|
||||||
uv_layer = bm.loops.layers.uv.new()
|
uv_layer = bm.loops.layers.uv.new()
|
||||||
else:
|
else:
|
||||||
uv_layer = bm.loops.layers.uv.active
|
uv_layer = bm.loops.layers.uv.active
|
||||||
|
|
||||||
if bm.verts:
|
if bm.verts:
|
||||||
min_x = min(v.co.x for v in bm.verts)
|
min_x = min(v.co.x for v in bm.verts)
|
||||||
max_x = max(v.co.x for v in bm.verts)
|
max_x = max(v.co.x for v in bm.verts)
|
||||||
min_y = min(v.co.y for v in bm.verts)
|
min_y = min(v.co.y for v in bm.verts)
|
||||||
max_y = max(v.co.y for v in bm.verts)
|
max_y = max(v.co.y for v in bm.verts)
|
||||||
|
|
||||||
width = max_x - min_x
|
width = max_x - min_x
|
||||||
height = max_y - min_y
|
height = max_y - min_y
|
||||||
|
|
||||||
for face in bm.faces:
|
for face in bm.faces:
|
||||||
for loop in face.loops:
|
for loop in face.loops:
|
||||||
vert = loop.vert
|
vert = loop.vert
|
||||||
u = (vert.co.x - min_x) / width if width > 0 else 0.5
|
u = (vert.co.x - min_x) / width if width > 0 else 0.5
|
||||||
v = (vert.co.y - min_y) / height if height > 0 else 0.5
|
v = (vert.co.y - min_y) / height if height > 0 else 0.5
|
||||||
|
|
||||||
u = max(0.0, min(1.0, u))
|
u = max(0.0, min(1.0, u))
|
||||||
v = max(0.0, min(1.0, v))
|
v = max(0.0, min(1.0, v))
|
||||||
|
|
||||||
loop[uv_layer].uv = (u, v)
|
loop[uv_layer].uv = (u, v)
|
||||||
|
|
||||||
bm.to_mesh(obj.data)
|
bm.to_mesh(obj.data)
|
||||||
bm.free()
|
bm.free()
|
||||||
obj.data.update()
|
obj.data.update()
|
||||||
|
|||||||
@@ -3688,7 +3688,7 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
description="Existing object name to add a style with reference image to. If not provided will create a new object.",
|
description="Existing object name to add a style with reference image to. If not provided will create a new object.",
|
||||||
options={"SKIP_SAVE"},
|
options={"SKIP_SAVE"},
|
||||||
)
|
)
|
||||||
|
|
||||||
x_length: bpy.props.FloatProperty(
|
x_length: bpy.props.FloatProperty(
|
||||||
name="X Length",
|
name="X Length",
|
||||||
description="Width of the reference image in project units",
|
description="Width of the reference image in project units",
|
||||||
@@ -3698,20 +3698,20 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
precision=3,
|
precision=3,
|
||||||
)
|
)
|
||||||
y_length: bpy.props.FloatProperty(
|
y_length: bpy.props.FloatProperty(
|
||||||
name="Y Length",
|
name="Y Length",
|
||||||
description="Height of the reference image in project units",
|
description="Height of the reference image in project units",
|
||||||
default=1.0,
|
default=1.0,
|
||||||
min=0.001,
|
min=0.001,
|
||||||
soft_min=0.01,
|
soft_min=0.01,
|
||||||
precision=3,
|
precision=3,
|
||||||
)
|
)
|
||||||
|
|
||||||
show_dimensions_dialog: bpy.props.BoolProperty(default=False, options={"HIDDEN", "SKIP_SAVE"})
|
show_dimensions_dialog: bpy.props.BoolProperty(default=False, options={"HIDDEN", "SKIP_SAVE"})
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
if getattr(self, 'show_dimensions_dialog', False):
|
if getattr(self, "show_dimensions_dialog", False):
|
||||||
if tool.Ifc.get():
|
if tool.Ifc.get():
|
||||||
length_unit = ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "LENGTHUNIT")
|
length_unit = ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "LENGTHUNIT")
|
||||||
if length_unit:
|
if length_unit:
|
||||||
@@ -3733,47 +3733,47 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
layout.label(text="to use relative paths.")
|
layout.label(text="to use relative paths.")
|
||||||
layout.prop(self, "override_existing_image")
|
layout.prop(self, "override_existing_image")
|
||||||
layout.prop(self, "use_existing_object_by_name")
|
layout.prop(self, "use_existing_object_by_name")
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
if not getattr(self, 'show_dimensions_dialog', False):
|
if not getattr(self, "show_dimensions_dialog", False):
|
||||||
context.window_manager.fileselect_add(self)
|
context.window_manager.fileselect_add(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {"RUNNING_MODAL"}
|
||||||
else:
|
else:
|
||||||
return context.window_manager.invoke_props_dialog(self)
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
if not getattr(self, 'show_dimensions_dialog', False):
|
if not getattr(self, "show_dimensions_dialog", False):
|
||||||
abs_path = Path(self.filepath).absolute().resolve()
|
abs_path = Path(self.filepath).absolute().resolve()
|
||||||
if self.override_existing_image:
|
if self.override_existing_image:
|
||||||
params = {"check_existing": True, "force_reload": True}
|
params = {"check_existing": True, "force_reload": True}
|
||||||
else:
|
else:
|
||||||
params = {"check_existing": False}
|
params = {"check_existing": False}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
image = load_image(abs_path.name, str(abs_path.parent), **params)
|
image = load_image(abs_path.name, str(abs_path.parent), **params)
|
||||||
|
|
||||||
image_width_px = image.size[0]
|
image_width_px = image.size[0]
|
||||||
image_height_px = image.size[1]
|
image_height_px = image.size[1]
|
||||||
aspect_ratio = image_width_px / image_height_px
|
aspect_ratio = image_width_px / image_height_px
|
||||||
|
|
||||||
if aspect_ratio >= 1.0:
|
if aspect_ratio >= 1.0:
|
||||||
self.x_length = 1.0
|
self.x_length = 1.0
|
||||||
self.y_length = 1.0 / aspect_ratio
|
self.y_length = 1.0 / aspect_ratio
|
||||||
else:
|
else:
|
||||||
self.x_length = aspect_ratio
|
self.x_length = aspect_ratio
|
||||||
self.y_length = 1.0
|
self.y_length = 1.0
|
||||||
|
|
||||||
bpy.data.images.remove(image)
|
bpy.data.images.remove(image)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.report({'ERROR'}, f"Failed to load image: {str(e)}")
|
self.report({"ERROR"}, f"Failed to load image: {str(e)}")
|
||||||
return {'CANCELLED'}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
self.show_dimensions_dialog = True
|
self.show_dimensions_dialog = True
|
||||||
return context.window_manager.invoke_props_dialog(self)
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
return self._execute(context)
|
return self._execute(context)
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
space = tool.Blender.get_view3d_space()
|
space = tool.Blender.get_view3d_space()
|
||||||
if space.shading.color_type != "TEXTURE":
|
if space.shading.color_type != "TEXTURE":
|
||||||
@@ -3795,7 +3795,7 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
|
|
||||||
def bm_add_image_plane(mesh):
|
def bm_add_image_plane(mesh):
|
||||||
bm = tool.Blender.get_bmesh_for_mesh(mesh, clean=True)
|
bm = tool.Blender.get_bmesh_for_mesh(mesh, clean=True)
|
||||||
|
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
|
||||||
plane_scale = Vector((self.x_length * unit_scale / 2.0, self.y_length * unit_scale / 2.0, 1.0))
|
plane_scale = Vector((self.x_length * unit_scale / 2.0, self.y_length * unit_scale / 2.0, 1.0))
|
||||||
matrix = Matrix.LocRotScale(None, None, plane_scale)
|
matrix = Matrix.LocRotScale(None, None, plane_scale)
|
||||||
@@ -3810,16 +3810,16 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
max_x = max(v.co.x for v in bm.verts)
|
max_x = max(v.co.x for v in bm.verts)
|
||||||
min_y = min(v.co.y for v in bm.verts)
|
min_y = min(v.co.y for v in bm.verts)
|
||||||
max_y = max(v.co.y for v in bm.verts)
|
max_y = max(v.co.y for v in bm.verts)
|
||||||
|
|
||||||
width = max_x - min_x
|
width = max_x - min_x
|
||||||
height = max_y - min_y
|
height = max_y - min_y
|
||||||
|
|
||||||
for face in bm.faces:
|
for face in bm.faces:
|
||||||
for loop in face.loops:
|
for loop in face.loops:
|
||||||
vert = loop.vert
|
vert = loop.vert
|
||||||
u = (vert.co.x - min_x) / width if width > 0 else 0.5
|
u = (vert.co.x - min_x) / width if width > 0 else 0.5
|
||||||
v = (vert.co.y - min_y) / height if height > 0 else 0.5
|
v = (vert.co.y - min_y) / height if height > 0 else 0.5
|
||||||
|
|
||||||
u = max(0.0, min(1.0, u))
|
u = max(0.0, min(1.0, u))
|
||||||
v = max(0.0, min(1.0, v))
|
v = max(0.0, min(1.0, v))
|
||||||
loop[uv_layer].uv = (u, v)
|
loop[uv_layer].uv = (u, v)
|
||||||
@@ -3844,7 +3844,6 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
)
|
)
|
||||||
tool.Blender.remove_data_block(temp_mesh)
|
tool.Blender.remove_data_block(temp_mesh)
|
||||||
|
|
||||||
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
if element and isinstance(obj.data, bpy.types.Mesh):
|
if element and isinstance(obj.data, bpy.types.Mesh):
|
||||||
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
||||||
@@ -3853,9 +3852,9 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
num_faces = len(obj.data.polygons)
|
num_faces = len(obj.data.polygons)
|
||||||
obj.data["ios_item_ids"] = [item_id] * num_faces
|
obj.data["ios_item_ids"] = [item_id] * num_faces
|
||||||
tool.Blender.Attribute.fill_attribute(obj.data, "ios_item_ids", "FACE", "INT", [item_id] * num_faces)
|
tool.Blender.Attribute.fill_attribute(obj.data, "ios_item_ids", "FACE", "INT", [item_id] * num_faces)
|
||||||
|
|
||||||
for item in representation.Items:
|
for item in representation.Items:
|
||||||
if item.is_a('IfcPolygonalFaceSet') and item.Coordinates:
|
if item.is_a("IfcPolygonalFaceSet") and item.Coordinates:
|
||||||
new_coords = []
|
new_coords = []
|
||||||
for vertex in obj.data.vertices:
|
for vertex in obj.data.vertices:
|
||||||
co = obj.matrix_world @ vertex.co
|
co = obj.matrix_world @ vertex.co
|
||||||
@@ -3901,8 +3900,8 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
)
|
)
|
||||||
tool.Style.reload_material_from_ifc(material)
|
tool.Style.reload_material_from_ifc(material)
|
||||||
tool.Geometry.record_object_materials(obj)
|
tool.Geometry.record_object_materials(obj)
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class ConvertSVGToDXF(bpy.types.Operator):
|
class ConvertSVGToDXF(bpy.types.Operator):
|
||||||
|
|||||||
@@ -131,4 +131,4 @@ def unregister():
|
|||||||
if kc:
|
if kc:
|
||||||
for km, kmi in addon_keymaps:
|
for km, kmi in addon_keymaps:
|
||||||
km.keymap_items.remove(kmi)
|
km.keymap_items.remove(kmi)
|
||||||
addon_keymaps.clear()
|
addon_keymaps.clear()
|
||||||
|
|||||||
@@ -2843,6 +2843,7 @@ class ClearMeasurement(bpy.types.Operator):
|
|||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
||||||
bl_idname = "bim.image_scaling_tool"
|
bl_idname = "bim.image_scaling_tool"
|
||||||
bl_label = "Image Scaling Tool"
|
bl_label = "Image Scaling Tool"
|
||||||
@@ -2862,7 +2863,7 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
self.current_distance_value = ""
|
self.current_distance_value = ""
|
||||||
self.is_typing_distance = False
|
self.is_typing_distance = False
|
||||||
self.calculated_distance = 0.0
|
self.calculated_distance = 0.0
|
||||||
|
|
||||||
if tool.Ifc.get():
|
if tool.Ifc.get():
|
||||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
else:
|
else:
|
||||||
@@ -2872,7 +2873,7 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
if not self.target_object or not context.active_object or context.active_object != self.target_object:
|
if not self.target_object or not context.active_object or context.active_object != self.target_object:
|
||||||
self.report({"ERROR"}, "Image annotation was deselected. Tool cancelled.")
|
self.report({"ERROR"}, "Image annotation was deselected. Tool cancelled.")
|
||||||
return self.cancel_tool(context)
|
return self.cancel_tool(context)
|
||||||
|
|
||||||
PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0])
|
PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0])
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
@@ -2891,9 +2892,9 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
if event.type == "LEFTMOUSE" and event.value == "PRESS":
|
if event.type == "LEFTMOUSE" and event.value == "PRESS":
|
||||||
if len(self.selected_points) < 2:
|
if len(self.selected_points) < 2:
|
||||||
snapped_point = self.snapping_points[0]
|
snapped_point = self.snapping_points[0]
|
||||||
point_3d = snapped_point['point'].copy()
|
point_3d = snapped_point["point"].copy()
|
||||||
self.selected_points.append(point_3d)
|
self.selected_points.append(point_3d)
|
||||||
|
|
||||||
if len(self.selected_points) == 2:
|
if len(self.selected_points) == 2:
|
||||||
self.calculate_distance()
|
self.calculate_distance()
|
||||||
self.current_distance_value = f"{self.calculated_distance:.3f}"
|
self.current_distance_value = f"{self.calculated_distance:.3f}"
|
||||||
@@ -2903,7 +2904,7 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
elif len(self.selected_points) == 2:
|
elif len(self.selected_points) == 2:
|
||||||
if event.type in {"RET", "NUMPAD_ENTER"} and event.value == "PRESS":
|
if event.type in {"RET", "NUMPAD_ENTER"} and event.value == "PRESS":
|
||||||
return self.apply_scaling(context)
|
return self.apply_scaling(context)
|
||||||
|
|
||||||
if event.unicode and event.unicode.isprintable() and event.value == "PRESS":
|
if event.unicode and event.unicode.isprintable() and event.value == "PRESS":
|
||||||
if event.unicode.isdigit() or event.unicode == ".":
|
if event.unicode.isdigit() or event.unicode == ".":
|
||||||
if not self.is_typing_distance:
|
if not self.is_typing_distance:
|
||||||
@@ -2911,14 +2912,16 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
self.is_typing_distance = True
|
self.is_typing_distance = True
|
||||||
else:
|
else:
|
||||||
self.current_distance_value += event.unicode
|
self.current_distance_value += event.unicode
|
||||||
|
|
||||||
distance_value = float(self.current_distance_value)
|
distance_value = float(self.current_distance_value)
|
||||||
self.input_ui.set_value("DISTANCE", distance_value)
|
self.input_ui.set_value("DISTANCE", distance_value)
|
||||||
|
|
||||||
elif event.type in {"BACK_SPACE", "DEL"} and event.value == "PRESS":
|
elif event.type in {"BACK_SPACE", "DEL"} and event.value == "PRESS":
|
||||||
if len(self.current_distance_value) > 0:
|
if len(self.current_distance_value) > 0:
|
||||||
self.current_distance_value = self.current_distance_value[:-1]
|
self.current_distance_value = self.current_distance_value[:-1]
|
||||||
distance_value = float(self.current_distance_value) if self.current_distance_value else self.calculated_distance
|
distance_value = (
|
||||||
|
float(self.current_distance_value) if self.current_distance_value else self.calculated_distance
|
||||||
|
)
|
||||||
self.input_ui.set_value("DISTANCE", distance_value)
|
self.input_ui.set_value("DISTANCE", distance_value)
|
||||||
|
|
||||||
self.handle_keyboard_input(context, event)
|
self.handle_keyboard_input(context, event)
|
||||||
@@ -2937,7 +2940,7 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
|
|
||||||
def cancel_tool(self, context):
|
def cancel_tool(self, context):
|
||||||
context.workspace.status_text_set(text=None)
|
context.workspace.status_text_set(text=None)
|
||||||
if hasattr(self, 'tool_state'):
|
if hasattr(self, "tool_state"):
|
||||||
self.tool_state.plane_method = None
|
self.tool_state.plane_method = None
|
||||||
PolylineDecorator.uninstall()
|
PolylineDecorator.uninstall()
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
@@ -2955,7 +2958,7 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
instruction_text = f"Measured: {self.calculated_distance:.3f} - Type New Distance or Press Enter"
|
instruction_text = f"Measured: {self.calculated_distance:.3f} - Type New Distance or Press Enter"
|
||||||
else:
|
else:
|
||||||
instruction_text = "Image Scaling Tool"
|
instruction_text = "Image Scaling Tool"
|
||||||
|
|
||||||
context.workspace.status_text_set(text=instruction_text)
|
context.workspace.status_text_set(text=instruction_text)
|
||||||
|
|
||||||
def calculate_distance(self):
|
def calculate_distance(self):
|
||||||
@@ -2984,51 +2987,51 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
|
|
||||||
if self.target_object:
|
if self.target_object:
|
||||||
import bmesh
|
import bmesh
|
||||||
|
|
||||||
mesh = self.target_object.data
|
mesh = self.target_object.data
|
||||||
|
|
||||||
bm = bmesh.new()
|
bm = bmesh.new()
|
||||||
bm.from_mesh(mesh)
|
bm.from_mesh(mesh)
|
||||||
|
|
||||||
bmesh.ops.scale(bm, vec=(scale_factor, scale_factor, 1.0), verts=bm.verts)
|
bmesh.ops.scale(bm, vec=(scale_factor, scale_factor, 1.0), verts=bm.verts)
|
||||||
|
|
||||||
if bm.loops.layers.uv:
|
if bm.loops.layers.uv:
|
||||||
uv_layer = bm.loops.layers.uv.active
|
uv_layer = bm.loops.layers.uv.active
|
||||||
|
|
||||||
min_x = min(v.co.x for v in bm.verts)
|
min_x = min(v.co.x for v in bm.verts)
|
||||||
max_x = max(v.co.x for v in bm.verts)
|
max_x = max(v.co.x for v in bm.verts)
|
||||||
min_y = min(v.co.y for v in bm.verts)
|
min_y = min(v.co.y for v in bm.verts)
|
||||||
max_y = max(v.co.y for v in bm.verts)
|
max_y = max(v.co.y for v in bm.verts)
|
||||||
|
|
||||||
width = max_x - min_x
|
width = max_x - min_x
|
||||||
height = max_y - min_y
|
height = max_y - min_y
|
||||||
|
|
||||||
for face in bm.faces:
|
for face in bm.faces:
|
||||||
for loop in face.loops:
|
for loop in face.loops:
|
||||||
vert = loop.vert
|
vert = loop.vert
|
||||||
u = (vert.co.x - min_x) / width if width > 0 else 0.5
|
u = (vert.co.x - min_x) / width if width > 0 else 0.5
|
||||||
v = (vert.co.y - min_y) / height if height > 0 else 0.5
|
v = (vert.co.y - min_y) / height if height > 0 else 0.5
|
||||||
|
|
||||||
u = max(0.0, min(1.0, u))
|
u = max(0.0, min(1.0, u))
|
||||||
v = max(0.0, min(1.0, v))
|
v = max(0.0, min(1.0, v))
|
||||||
loop[uv_layer].uv = (u, v)
|
loop[uv_layer].uv = (u, v)
|
||||||
|
|
||||||
bm.to_mesh(mesh)
|
bm.to_mesh(mesh)
|
||||||
bm.free()
|
bm.free()
|
||||||
mesh.update()
|
mesh.update()
|
||||||
|
|
||||||
element = tool.Ifc.get_entity(self.target_object)
|
element = tool.Ifc.get_entity(self.target_object)
|
||||||
if element and element.Representation:
|
if element and element.Representation:
|
||||||
for representation in element.Representation.Representations:
|
for representation in element.Representation.Representations:
|
||||||
for item in representation.Items:
|
for item in representation.Items:
|
||||||
if item.is_a('IfcPolygonalFaceSet') and item.Coordinates:
|
if item.is_a("IfcPolygonalFaceSet") and item.Coordinates:
|
||||||
new_coords = []
|
new_coords = []
|
||||||
for vertex in mesh.vertices:
|
for vertex in mesh.vertices:
|
||||||
co = self.target_object.matrix_world @ vertex.co
|
co = self.target_object.matrix_world @ vertex.co
|
||||||
new_coords.append([co.x, co.y, co.z])
|
new_coords.append([co.x, co.y, co.z])
|
||||||
|
|
||||||
item.Coordinates.CoordList = new_coords
|
item.Coordinates.CoordList = new_coords
|
||||||
|
|
||||||
self.report({"INFO"}, f"Applied scale factor: {scale_factor:.4f}")
|
self.report({"INFO"}, f"Applied scale factor: {scale_factor:.4f}")
|
||||||
|
|
||||||
context.workspace.status_text_set(text=None)
|
context.workspace.status_text_set(text=None)
|
||||||
@@ -3037,5 +3040,3 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class ExploreTool(bpy.types.WorkSpaceTool):
|
|||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
op = row.operator("bim.explore_hotkey", text="Image Scaling Tool", icon="IMAGE_PLANE")
|
op = row.operator("bim.explore_hotkey", text="Image Scaling Tool", icon="IMAGE_PLANE")
|
||||||
op.hotkey = "S_S"
|
op.hotkey = "S_S"
|
||||||
|
op.description = "Scale Image Annotation. Allows to scale an IfcReferenceImage. Select image, select tool. Check lower left corner instructions to select two points and provide real distance between them"
|
||||||
|
|
||||||
|
|
||||||
class ExploreHotkey(bpy.types.Operator):
|
class ExploreHotkey(bpy.types.Operator):
|
||||||
@@ -123,12 +124,14 @@ class ExploreHotkey(bpy.types.Operator):
|
|||||||
active_obj = bpy.context.active_object
|
active_obj = bpy.context.active_object
|
||||||
selected_objects = tool.Blender.get_selected_objects()
|
selected_objects = tool.Blender.get_selected_objects()
|
||||||
element = tool.Ifc.get_entity(active_obj) if active_obj else None
|
element = tool.Ifc.get_entity(active_obj) if active_obj else None
|
||||||
|
|
||||||
if (not active_obj or
|
if (
|
||||||
not element or
|
not active_obj
|
||||||
not element.is_a("IfcAnnotation") or
|
or not element
|
||||||
len(selected_objects) != 1 or
|
or not element.is_a("IfcAnnotation")
|
||||||
not tool.Drawing.is_annotation_object_type(element, "IMAGE")):
|
or len(selected_objects) != 1
|
||||||
|
or not tool.Drawing.is_annotation_object_type(element, "IMAGE")
|
||||||
|
):
|
||||||
self.report({"ERROR"}, "Please select one image annotation first.")
|
self.report({"ERROR"}, "Please select one image annotation first.")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user