Refactor - moved some helpers functions to tool

This commit is contained in:
Andrej730
2023-02-16 15:15:28 +05:00
parent 1617ede010
commit a85f81d8ca
10 changed files with 114 additions and 110 deletions
-29
View File
@@ -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
@@ -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
@@ -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 <http://www.gnu.org/licenses/>.
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,
)
@@ -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]
@@ -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
@@ -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
+22 -1
View File
@@ -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
+2 -1
View File
@@ -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
from blenderbim.tool.cost import Cost
+28
View File
@@ -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,
)
+54
View File
@@ -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 <http://www.gnu.org/licenses/>.
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)