Skip to content

Commit

Permalink
prioritize external styles on ifc import
Browse files Browse the repository at this point in the history
also found a way to switch shade graph for two materials without juggling active materials and active objects - it was necessary to make it work on import without adding temporary active object
  • Loading branch information
Andrej730 committed Jun 12, 2023
1 parent 62944e0 commit 7c0c934
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 39 deletions.
21 changes: 5 additions & 16 deletions src/blenderbim/blenderbim/bim/import_ifc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1485,22 +1485,11 @@ def create_style(self, style, blender_material=None):
blender_material.BIMMaterialProperties.ifc_style_id = style.id()
self.material_creator.styles[style.id()] = blender_material

rendering_style = None
texture_style = None

for surface_style in style.Styles:
if surface_style.is_a() == "IfcSurfaceStyleShading":
tool.Loader.create_surface_style_shading(blender_material, surface_style)
elif surface_style.is_a("IfcSurfaceStyleRendering"):
rendering_style = surface_style
tool.Loader.create_surface_style_rendering(blender_material, surface_style)
elif surface_style.is_a("IfcSurfaceStyleWithTextures"):
texture_style = surface_style

if rendering_style and texture_style:
tool.Loader.create_surface_style_with_textures(blender_material, rendering_style, texture_style)

tool.Style.record_shading(blender_material)
style_elements = tool.Style.get_style_elements(blender_material)
if tool.Style.has_blender_external_style(style_elements):
blender_material.BIMStyleProperties.active_style_type = "External"
else:
blender_material.BIMStyleProperties.active_style_type = "Shading"

def place_objects_in_collections(self):
for ifc_definition_id, obj in self.added_data.items():
Expand Down
9 changes: 7 additions & 2 deletions src/blenderbim/blenderbim/bim/module/style/operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,13 @@ class ActivateExternalStyle(bpy.types.Operator, tool.Ifc.Operator):
bl_label = "Activate External Style"
bl_options = {"REGISTER", "UNDO", "INTERNAL"}

material_name: bpy.props.StringProperty(name="Material Name", default="")

def _execute(self, context):
material = context.active_object.active_material
if not self.material_name:
material = context.active_object.active_material
else:
material = bpy.data.materials[self.material_name]
external_style = tool.Style.get_style_elements(material)["IfcExternallyDefinedSurfaceStyle"]
data_block_type, data_block = external_style.Identification.split("/")
style_path = Path(tool.Ifc.resolve_uri(external_style.Location))
Expand Down Expand Up @@ -297,7 +302,7 @@ def _execute(self, context):
setattr(material, prop_name, getattr(db["data_block"], prop_name))

if material.use_nodes:
tool.Blender.copy_node_graph_to_active_object(context, db["data_block"])
tool.Blender.copy_node_graph(material, db["data_block"])
bpy.data.materials.remove(db["data_block"])


Expand Down
9 changes: 5 additions & 4 deletions src/blenderbim/blenderbim/bim/module/style/prop.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def update_shading_styles(self, context):
materials_to_objects[blender_material] = obj

for mat, obj in materials_to_objects.items():
tool.Style.change_current_style_type(context, obj, mat, self.active_style_type)
tool.Style.change_current_style_type(mat, self.active_style_type)


class BIMStylesProperties(PropertyGroup):
Expand All @@ -79,11 +79,11 @@ class BIMStylesProperties(PropertyGroup):


def update_shading_style(self, context):
blender_material = context.active_object.active_material
blender_material = self.id_data
style_elements = tool.Style.get_style_elements(blender_material)
if self.active_style_type == "External":
if "IfcExternallyDefinedSurfaceStyle" in style_elements:
bpy.ops.bim.activate_external_style()
if tool.Style.has_blender_external_style(style_elements):
bpy.ops.bim.activate_external_style(material_name=blender_material.name)

elif self.active_style_type == "Shading":
style_elements = tool.Style.get_style_elements(blender_material)
Expand All @@ -101,6 +101,7 @@ def update_shading_style(self, context):

if rendering_style and texture_style:
tool.Loader.create_surface_style_with_textures(blender_material, rendering_style, texture_style)
tool.Style.record_shading(blender_material)


class BIMStyleProperties(PropertyGroup):
Expand Down
27 changes: 13 additions & 14 deletions src/blenderbim/blenderbim/tool/blender.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,32 +118,31 @@ def get_shader_editor_context(cls):
return context_override

@classmethod
def copy_node_graph_to_active_object(cls, context, material):
"""make sure to override `context.active_object`
to you want change node graph for the object that's not actually active
"""
def copy_node_graph(cls, material_to, material_from):
temp_override = cls.get_shader_editor_context()
old_material = context.active_object.active_material
new_material = material
shader_editor = temp_override["space"]

# remove all nodes from the current material
for n in old_material.node_tree.nodes[:]:
old_material.node_tree.nodes.remove(n)
for n in material_to.node_tree.nodes[:]:
material_to.node_tree.nodes.remove(n)

# change current material and make other window's shader editor is updated
context.active_object.active_material = new_material
temp_override["space"].node_tree = new_material.node_tree
previous_pin_setting = shader_editor.pin
# required to be able to change material to something else
shader_editor.pin = True
shader_editor.node_tree = material_from.node_tree

# select all nodes and copy them to clipboard
for node in new_material.node_tree.nodes:
for node in material_from.node_tree.nodes:
node.select = True
bpy.ops.node.clipboard_copy(temp_override)

# back to original material
context.active_object.active_material = old_material
temp_override["space"].node_tree = old_material.node_tree
shader_editor.node_tree = material_to.node_tree
bpy.ops.node.clipboard_paste(temp_override, offset=(0, 0))

# restore shader editor settings
shader_editor.pin = previous_pin_setting

@classmethod
def update_screen(cls):
bpy.ops.wm.redraw_timer(type="DRAW_WIN_SWAP", iterations=1)
Expand Down
10 changes: 7 additions & 3 deletions src/blenderbim/blenderbim/tool/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ def import_external_style_attributes(cls, style, obj):
attributes.clear()
blenderbim.bim.helper.import_attributes2(style, attributes)

@classmethod
def has_blender_external_style(cls, style_elements):
external_style = style_elements.get("IfcExternallyDefinedSurfaceStyle", None)
return bool(external_style and external_style.Location.endswith(".blend"))

@classmethod
def is_editing_styles(cls):
return bpy.context.scene.BIMStylesProperties.is_editing
Expand All @@ -243,6 +248,5 @@ def select_elements(cls, elements):
obj.select_set(True)

@classmethod
def change_current_style_type(cls, context, obj, blender_material, style_type):
with context.temp_override(active_object=obj):
blender_material.BIMStyleProperties.active_style_type = style_type
def change_current_style_type(cls, blender_material, style_type):
blender_material.BIMStyleProperties.active_style_type = style_type

0 comments on commit 7c0c934

Please sign in to comment.