diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py
index 38af2fc914..cf1018c3d7 100644
--- a/src/blenderbim/blenderbim/bim/helper.py
+++ b/src/blenderbim/blenderbim/bim/helper.py
@@ -267,35 +267,6 @@ def convert_property_group_from_si(property_group, skip_props=()):
setattr(property_group, prop_name, prop_value)
-def draw_image_for_ifc_profile(draw, profile, size):
- """generates image based on `profile` using `PIL.ImageDraw`"""
- settings = ifcopenshell.geom.settings()
- settings.set(settings.INCLUDE_CURVES, True)
- shape = ifcopenshell.geom.create_shape(settings, profile)
- verts = shape.verts
- edges = shape.edges
-
- grouped_verts = [[verts[i], verts[i + 1]] for i in range(0, len(verts), 3)]
- grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
-
- max_x = max([v[0] for v in grouped_verts])
- min_x = min([v[0] for v in grouped_verts])
- max_y = max([v[1] for v in grouped_verts])
- min_y = min([v[1] for v in grouped_verts])
-
- dim_x = max_x - min_x
- dim_y = max_y - min_y
- max_dim = max([dim_x, dim_y])
- scale = 100 / max_dim
-
- for vert in grouped_verts:
- vert[0] = round(scale * (vert[0] - min_x)) + ((size / 2) - scale * (dim_x / 2))
- vert[1] = round(scale * (vert[1] - min_y)) + ((size / 2) - scale * (dim_y / 2))
-
- for e in grouped_edges:
- draw.line((tuple(grouped_verts[e[0]]), tuple(grouped_verts[e[1]])), fill="white", width=2)
-
-
class IfcHeaderExtractor:
def __init__(self, filepath: str):
self.filepath = filepath
diff --git a/src/blenderbim/blenderbim/bim/module/model/door.py b/src/blenderbim/blenderbim/bim/module/model/door.py
index 699c08c92b..0cf815ec07 100644
--- a/src/blenderbim/blenderbim/bim/module/model/door.py
+++ b/src/blenderbim/blenderbim/bim/module/model/door.py
@@ -30,7 +30,6 @@ import blenderbim.core.geometry as core
from blenderbim.bim.helper import convert_property_group_from_si
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.model.window import create_bm_window, create_bm_box, update_simple_openings
-from blenderbim.bim.module.model.helper import replace_ifc_representation_for_object
from mathutils import Vector, Matrix
from pprint import pprint
@@ -80,20 +79,20 @@ def update_door_modifier_representation(context):
elevation_representation = ifcopenshell.api.run(
"geometry.add_door_representation", ifc_file, **representation_data
)
- replace_ifc_representation_for_object(ifc_file, profile, obj, elevation_representation)
+ tool.Model.replace_object_ifc_representation(profile, obj, elevation_representation)
# MODEL_VIEW representation
body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW")
representation_data["context"] = body
model_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data)
- replace_ifc_representation_for_object(ifc_file, body, obj, model_representation)
+ tool.Model.replace_object_ifc_representation(body, obj, model_representation)
# PLAN_VIEW representation
plan = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "Body", "PLAN_VIEW")
if plan:
representation_data["context"] = plan
plan_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data)
- replace_ifc_representation_for_object(ifc_file, plan, obj, plan_representation)
+ tool.Model.replace_object_ifc_representation(plan, obj, plan_representation)
# adding switch representation at the end instead of changing order of representations
# to prevent #2744
diff --git a/src/blenderbim/blenderbim/bim/module/model/helper.py b/src/blenderbim/blenderbim/bim/module/model/helper.py
deleted file mode 100644
index 1666c07877..0000000000
--- a/src/blenderbim/blenderbim/bim/module/model/helper.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# BlenderBIM Add-on - OpenBIM Blender Add-on
-# Copyright (C) 2023 @Andrej730
-#
-# This file is part of BlenderBIM Add-on.
-#
-# BlenderBIM Add-on is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# BlenderBIM Add-on is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with BlenderBIM Add-on. If not, see .
-
-import bpy
-import bmesh
-import ifcopenshell
-import ifcopenshell.util.unit
-import blenderbim.core.geometry as core
-import blenderbim.tool as tool
-
-
-def get_ifc_context_or_create(ifc_file, context_type, context_identifier, target_view):
- ifc_context = ifcopenshell.util.representation.get_context(ifc_file, context_type, context_identifier, target_view)
- if not ifc_context:
- parent_context = ifcopenshell.util.representation.get_context(ifc_file, context_type)
- ifc_context = ifcopenshell.api.run(
- "context.add_context",
- ifc_file,
- context_type=context_type,
- context_identifier=context_identifier,
- target_view=target_view,
- parent=parent_context,
- )
- return ifc_context
-
-
-def replace_ifc_representation_for_object(ifc_file, ifc_context, obj, new_representation):
- ifc_element = tool.Ifc.get_entity(obj)
- old_representation = ifcopenshell.util.representation.get_representation(
- ifc_element, ifc_context.ContextType, ifc_context.ContextIdentifier, ifc_context.TargetView
- )
-
- if old_representation:
- old_representation = tool.Geometry.resolve_mapped_representation(old_representation)
- for inverse in ifc_file.get_inverse(old_representation):
- ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation)
- ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=old_representation)
- else:
- ifcopenshell.api.run(
- "geometry.assign_representation", ifc_file, product=ifc_element, representation=new_representation
- )
- core.switch_representation(
- tool.Ifc,
- tool.Geometry,
- obj=obj,
- representation=new_representation,
- should_reload=True,
- is_global=True,
- should_sync_changes_first=False,
- )
-
-
diff --git a/src/blenderbim/blenderbim/bim/module/model/product.py b/src/blenderbim/blenderbim/bim/module/model/product.py
index 1c70b83d3a..87424b06ae 100644
--- a/src/blenderbim/blenderbim/bim/module/model/product.py
+++ b/src/blenderbim/blenderbim/bim/module/model/product.py
@@ -32,7 +32,6 @@ from . import wall, slab, profile, mep
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.model.data import AuthoringData
from blenderbim.bim.module.model.prop import store_cursor_position
-from blenderbim.bim.helper import draw_image_for_ifc_profile
from mathutils import Vector, Matrix
from bpy_extras.object_utils import AddObjectHelper
from . import prop
@@ -374,7 +373,7 @@ class LoadTypeThumbnails(bpy.types.Operator, tool.Ifc.Operator):
material = ifcopenshell.util.element.get_material(element)
if material and material.is_a("IfcMaterialProfileSet"):
profile = material.MaterialProfiles[0].Profile
- draw_image_for_ifc_profile(draw, profile, size)
+ tool.Profile.draw_image_for_ifc_profile(draw, profile, size)
elif material and material.is_a("IfcMaterialLayerSet"):
thicknesses = [l.LayerThickness for l in material.MaterialLayers]
diff --git a/src/blenderbim/blenderbim/bim/module/model/window.py b/src/blenderbim/blenderbim/bim/module/model/window.py
index c925766778..c3d27c7e18 100644
--- a/src/blenderbim/blenderbim/bim/module/model/window.py
+++ b/src/blenderbim/blenderbim/bim/module/model/window.py
@@ -32,7 +32,6 @@ from bpy.props import FloatProperty, IntProperty, BoolProperty
from bmesh.types import BMVert
from blenderbim.bim.helper import convert_property_group_from_si
from blenderbim.bim.ifc import IfcStore
-from blenderbim.bim.module.model.helper import replace_ifc_representation_for_object
from mathutils import Vector
@@ -148,13 +147,13 @@ def update_window_modifier_representation(context):
elevation_representation = ifcopenshell.api.run(
"geometry.add_window_representation", ifc_file, **representation_data
)
- replace_ifc_representation_for_object(ifc_file, profile, obj, elevation_representation)
+ tool.Model.replace_object_ifc_representation(profile, obj, elevation_representation)
# MODEL_VIEW representation
body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW")
representation_data["context"] = body
model_representation = ifcopenshell.api.run("geometry.add_window_representation", ifc_file, **representation_data)
- replace_ifc_representation_for_object(ifc_file, body, obj, model_representation)
+ tool.Model.replace_object_ifc_representation(body, obj, model_representation)
# PLAN_VIEW representation
plan = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "Body", "PLAN_VIEW")
@@ -163,7 +162,7 @@ def update_window_modifier_representation(context):
plan_representation = ifcopenshell.api.run(
"geometry.add_window_representation", ifc_file, **representation_data
)
- replace_ifc_representation_for_object(ifc_file, plan, obj, plan_representation)
+ tool.Model.replace_object_ifc_representation(plan, obj, plan_representation)
# adding switch representation at the end instead of changing order of representations
# to prevent #2744
diff --git a/src/blenderbim/blenderbim/bim/module/profile/prop.py b/src/blenderbim/blenderbim/bim/module/profile/prop.py
index 346149b7ba..747831e98d 100644
--- a/src/blenderbim/blenderbim/bim/module/profile/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/profile/prop.py
@@ -24,7 +24,6 @@ import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.prop import StrProperty, Attribute
from blenderbim.bim.module.profile.data import ProfileData
-from blenderbim.bim.helper import draw_image_for_ifc_profile
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
@@ -79,7 +78,7 @@ def generate_thumbnail_for_active_profile():
size = 128
img = Image.new("RGBA", (size, size))
draw = ImageDraw.Draw(img)
- draw_image_for_ifc_profile(draw, profile, size)
+ tool.Profile.draw_image_for_ifc_profile(draw, profile, size)
pixels = [item for sublist in img.getdata() for item in sublist]
# save generated image to preview collection
diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py
index 94221f45dc..34f7a748a5 100644
--- a/src/blenderbim/blenderbim/core/tool.py
+++ b/src/blenderbim/blenderbim/core/tool.py
@@ -398,7 +398,23 @@ class Misc:
@interface
class Model:
- pass
+ def convert_si_to_unit(cls, value): pass
+ def convert_unit_to_si(cls, value): pass
+ def export_curve(cls, position, edge_indices, points=None): pass
+ def export_points(cls, position, indices): pass
+ def export_profile(cls, obj, position=None): pass
+ def generate_occurrence_name(cls, element_type, ifc_class): pass
+ def get_extrusion(cls, representation): pass
+ def import_profile(cls, profile, obj=None, position=None): pass
+ def import_curve(cls, obj, position, curve): pass
+ def import_rectangle(cls, obj, position, profile): pass
+ def load_openings(cls, element, openings): pass
+ def clear_scene_openings(cls): pass
+ def get_material_layer_parameters(cls, element): pass
+ def get_manual_booleans(cls, element): pass
+ def get_wall_axis(cls, obj, layers=None): pass
+ def regenerate_array(cls, parent, data): pass
+ def replace_object_ifc_representation(cls, ifc_file, ifc_context, obj, new_representation): pass
@interface
@@ -461,6 +477,11 @@ class Project:
def set_default_modeling_dimensions(cls): pass
+@interface
+class Profile:
+ def draw_image_for_ifc_profile(cls, draw, profile, size): pass
+
+
@interface
class Pset:
def get_element_pset(cls, element, pset_name): pass
diff --git a/src/blenderbim/blenderbim/tool/__init__.py b/src/blenderbim/blenderbim/tool/__init__.py
index f011bf6039..5ccefb71be 100644
--- a/src/blenderbim/blenderbim/tool/__init__.py
+++ b/src/blenderbim/blenderbim/tool/__init__.py
@@ -38,6 +38,7 @@ from blenderbim.tool.model import Model
from blenderbim.tool.owner import Owner
from blenderbim.tool.patch import Patch
from blenderbim.tool.project import Project
+from blenderbim.tool.profile import Profile
from blenderbim.tool.pset import Pset
from blenderbim.tool.qto import Qto
from blenderbim.tool.resource import Resource
@@ -51,4 +52,4 @@ from blenderbim.tool.system import System
from blenderbim.tool.type import Type
from blenderbim.tool.unit import Unit
from blenderbim.tool.search import Search
-from blenderbim.tool.cost import Cost
\ No newline at end of file
+from blenderbim.tool.cost import Cost
diff --git a/src/blenderbim/blenderbim/tool/model.py b/src/blenderbim/blenderbim/tool/model.py
index 1ccf6126da..f450b1b172 100644
--- a/src/blenderbim/blenderbim/tool/model.py
+++ b/src/blenderbim/blenderbim/tool/model.py
@@ -24,6 +24,7 @@ import ifcopenshell.util.placement
import ifcopenshell.util.representation
import blenderbim.core.tool
import blenderbim.tool as tool
+import blenderbim.core.geometry as geometry
from mathutils import Matrix, Vector
from blenderbim.bim import import_ifc
from blenderbim.bim.module.geometry.helper import Helper
@@ -408,3 +409,30 @@ class Model(blenderbim.core.tool.Model):
# TODO: Not sufficient, refactor OverrideDeleteTrait
bpy.context.view_layer.update()
+
+ @classmethod
+ def replace_object_ifc_representation(cls, ifc_context, obj, new_representation):
+ ifc_file = tool.Ifc.get()
+ ifc_element = tool.Ifc.get_entity(obj)
+ old_representation = ifcopenshell.util.representation.get_representation(
+ ifc_element, ifc_context.ContextType, ifc_context.ContextIdentifier, ifc_context.TargetView
+ )
+
+ if old_representation:
+ old_representation = tool.Geometry.resolve_mapped_representation(old_representation)
+ for inverse in ifc_file.get_inverse(old_representation):
+ ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation)
+ ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=old_representation)
+ else:
+ ifcopenshell.api.run(
+ "geometry.assign_representation", ifc_file, product=ifc_element, representation=new_representation
+ )
+ geometry.switch_representation(
+ tool.Ifc,
+ tool.Geometry,
+ obj=obj,
+ representation=new_representation,
+ should_reload=True,
+ is_global=True,
+ should_sync_changes_first=False,
+ )
diff --git a/src/blenderbim/blenderbim/tool/profile.py b/src/blenderbim/blenderbim/tool/profile.py
new file mode 100644
index 0000000000..ab1402daaf
--- /dev/null
+++ b/src/blenderbim/blenderbim/tool/profile.py
@@ -0,0 +1,54 @@
+# BlenderBIM Add-on - OpenBIM Blender Add-on
+# Copyright (C) 2022 @Andrej730
+#
+# This file is part of BlenderBIM Add-on.
+#
+# BlenderBIM Add-on is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# BlenderBIM Add-on is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with BlenderBIM Add-on. If not, see .
+
+import ifcopenshell
+import ifcopenshell.util.unit
+import ifcopenshell.util.placement
+import ifcopenshell.util.representation
+import blenderbim.core.tool
+
+
+class Profile(blenderbim.core.tool.Profile):
+ @classmethod
+ def draw_image_for_ifc_profile(cls, draw, profile, size):
+ """generates image based on `profile` using `PIL.ImageDraw`"""
+ settings = ifcopenshell.geom.settings()
+ settings.set(settings.INCLUDE_CURVES, True)
+ shape = ifcopenshell.geom.create_shape(settings, profile)
+ verts = shape.verts
+ edges = shape.edges
+
+ grouped_verts = [[verts[i], verts[i + 1]] for i in range(0, len(verts), 3)]
+ grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
+
+ max_x = max([v[0] for v in grouped_verts])
+ min_x = min([v[0] for v in grouped_verts])
+ max_y = max([v[1] for v in grouped_verts])
+ min_y = min([v[1] for v in grouped_verts])
+
+ dim_x = max_x - min_x
+ dim_y = max_y - min_y
+ max_dim = max([dim_x, dim_y])
+ scale = 100 / max_dim
+
+ for vert in grouped_verts:
+ vert[0] = round(scale * (vert[0] - min_x)) + ((size / 2) - scale * (dim_x / 2))
+ vert[1] = round(scale * (vert[1] - min_y)) + ((size / 2) - scale * (dim_y / 2))
+
+ for e in grouped_edges:
+ draw.line((tuple(grouped_verts[e[0]]), tuple(grouped_verts[e[1]])), fill="white", width=2)