mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
bonsai, ifcopenshell - append IfcSurfaceStyles from other projects
And other IfcPresentationStyles, though they are not currently supported by bonsai. Example - https://imgur.com/a/AHlvowp
This commit is contained in:
@@ -201,8 +201,7 @@ class RefreshLibrary(bpy.types.Operator):
|
||||
|
||||
types = IfcStore.library_file.wrapped_data.types_with_super()
|
||||
|
||||
element_classes = ["IfcTypeProduct", "IfcMaterial", "IfcCostSchedule", "IfcProfileDef"]
|
||||
for importable_type in sorted(element_classes):
|
||||
for importable_type in sorted(tool.Project.get_appendable_asset_types()):
|
||||
if importable_type in types:
|
||||
new = self.props.library_elements.add()
|
||||
new.name = importable_type
|
||||
@@ -384,9 +383,8 @@ class AppendEntireLibrary(bpy.types.Operator):
|
||||
self.file = IfcStore.get_file()
|
||||
self.library = IfcStore.library_file
|
||||
|
||||
lib_elements = ifcopenshell.util.selector.filter_elements(
|
||||
self.library, "IfcTypeProduct, IfcMaterial, IfcCostSchedule, IfcProfileDef"
|
||||
)
|
||||
query = ", ".join(tool.Project.get_appendable_asset_types())
|
||||
lib_elements = ifcopenshell.util.selector.filter_elements(self.library, query)
|
||||
for element in lib_elements:
|
||||
bpy.ops.bim.append_library_element(definition=element.id())
|
||||
return {"FINISHED"}
|
||||
@@ -456,9 +454,11 @@ class AppendLibraryElement(bpy.types.Operator):
|
||||
obj = tool.Ifc.get_object(element_type)
|
||||
if obj is None:
|
||||
self.import_type_from_ifc(element_type, context)
|
||||
|
||||
elif element.is_a("IfcMaterial"):
|
||||
self.import_material_from_ifc(element, context)
|
||||
elif element.is_a("IfcPresentationStyle"):
|
||||
self.import_presentation_style_from_ifc(element, context)
|
||||
|
||||
try:
|
||||
context.scene.BIMProjectProperties.library_elements[self.prop_index].is_appended = True
|
||||
except:
|
||||
@@ -475,6 +475,16 @@ class AppendLibraryElement(bpy.types.Operator):
|
||||
ifc_importer.file = self.file
|
||||
self.import_material_styles(element, ifc_importer)
|
||||
|
||||
def import_presentation_style_from_ifc(
|
||||
self, style: ifcopenshell.entity_instance, context: bpy.types.Context
|
||||
) -> None:
|
||||
self.file = tool.Ifc.get()
|
||||
logger = logging.getLogger("ImportIFC")
|
||||
ifc_import_settings = import_ifc.IfcImportSettings.factory(context, tool.Ifc.get_path(), logger)
|
||||
ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
|
||||
ifc_importer.file = self.file
|
||||
ifc_importer.create_style(style)
|
||||
|
||||
def import_product_from_ifc(self, element: ifcopenshell.entity_instance, context: bpy.types.Context) -> None:
|
||||
self.file = IfcStore.get_file()
|
||||
logger = logging.getLogger("ImportIFC")
|
||||
|
||||
@@ -30,6 +30,7 @@ import bonsai.core.owner
|
||||
import bonsai.bim.schema
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.project.append_asset import APPENDABLE_ASSET_TYPES
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
@@ -204,3 +205,7 @@ class Project(bonsai.core.tool.Project):
|
||||
@classmethod
|
||||
def clear_recent_ifc_projects(cls) -> None:
|
||||
cls.write_recent_ifc_projects([])
|
||||
|
||||
@classmethod
|
||||
def get_appendable_asset_types(cls) -> tuple[str, ...]:
|
||||
return tuple(e for e in APPENDABLE_ASSET_TYPES if e != "IfcProduct")
|
||||
|
||||
@@ -25,7 +25,18 @@ import ifcopenshell.api.owner.settings
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.geolocation
|
||||
import ifcopenshell.util.placement
|
||||
from typing import Optional, Any, Union
|
||||
from typing import Optional, Any, Union, Literal, get_args
|
||||
|
||||
|
||||
APPENDABLE_ASSET = Literal[
|
||||
"IfcTypeProduct",
|
||||
"IfcProduct",
|
||||
"IfcMaterial",
|
||||
"IfcCostSchedule",
|
||||
"IfcProfileDef",
|
||||
"IfcPresentationStyle",
|
||||
]
|
||||
APPENDABLE_ASSET_TYPES = get_args(APPENDABLE_ASSET)
|
||||
|
||||
|
||||
def append_asset(
|
||||
@@ -154,6 +165,9 @@ class Usecase:
|
||||
elif self.settings["element"].is_a("IfcProfileDef"):
|
||||
self.target_class = "IfcProfileDef"
|
||||
return self.append_profile_def()
|
||||
elif self.settings["element"].is_a("IfcPresentationStyle"):
|
||||
self.target_class = "IfcPresentationStyle"
|
||||
return self.append_presentation_style()
|
||||
|
||||
def get_existing_element(self, element):
|
||||
if element.id() in self.added_elements:
|
||||
@@ -186,6 +200,10 @@ class Usecase:
|
||||
self.whitelisted_inverse_attributes = {"IfcProfileDef": ["HasProperties"]}
|
||||
return self.add_element(self.settings["element"])
|
||||
|
||||
def append_presentation_style(self):
|
||||
self.whitelisted_inverse_attributes = {}
|
||||
return self.add_element(self.settings["element"])
|
||||
|
||||
def append_type_product(self):
|
||||
self.whitelisted_inverse_attributes = {
|
||||
"IfcObjectDefinition": ["HasAssociations"],
|
||||
|
||||
@@ -408,6 +408,31 @@ class TestAppendAssetIFC2X3(test.bootstrap.IFC2X3):
|
||||
)
|
||||
assert np.array_equal(ifcopenshell.util.placement.get_local_placement(new.ObjectPlacement), resulting_matrix)
|
||||
|
||||
def test_append_a_surface_style(self):
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
library = ifcopenshell.api.project.create_file(version=self.file.schema)
|
||||
ifcopenshell.api.root.create_entity(library, ifc_class="IfcProject")
|
||||
|
||||
style_name = "New Style"
|
||||
style = ifcopenshell.api.style.add_style(library, style_name)
|
||||
shading_attrs = {"SurfaceColour": {"Name": "", "Red": 1, "Green": 1, "Blue": 1}}
|
||||
ifcopenshell.api.style.add_surface_style(
|
||||
library, style, ifc_class="IfcSurfaceStyleShading", attributes=shading_attrs
|
||||
)
|
||||
|
||||
new_style = ifcopenshell.api.project.append_asset(self.file, library=library, element=style)
|
||||
assert self.file.by_type("IfcSurfaceStyle") == [new_style]
|
||||
assert new_style.Name == style_name
|
||||
style_elements = new_style.Styles
|
||||
assert len(style_elements) == 1
|
||||
|
||||
# Check shading style.
|
||||
shading_style = style_elements[0]
|
||||
assert shading_style.is_a("IfcSurfaceStyleShading")
|
||||
shading_colour_info = shading_style.SurfaceColour.get_info()
|
||||
del shading_colour_info["id"], shading_colour_info["type"]
|
||||
assert shading_colour_info == shading_attrs["SurfaceColour"]
|
||||
|
||||
|
||||
class TestAppendAssetIFC4(test.bootstrap.IFC4, TestAppendAssetIFC2X3):
|
||||
# NOTE: breaks in IFC2X3 since IfcProfileDef doesn't have "HasProperties" inverse in ifc2x3
|
||||
|
||||
Reference in New Issue
Block a user