Skip to content

Commit 0aaafae

Browse files
authored
Merge pull request #8014 from falken10vdl/surface-style-small-fixes
Surface styles fixes and message warnings
2 parents 6d3bed1 + 7881f59 commit 0aaafae

4 files changed

Lines changed: 105 additions & 33 deletions

File tree

src/bonsai/bonsai/bim/module/style/operator.py

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ def execute(self, context):
744744
if self.ifc_class == "IfcSurfaceStyleLighting":
745745

746746
def callback(attribute_name: str, _: object, data: dict[str, Any]) -> None:
747-
assert attributes
747+
assert attributes is not None
748748
color = attributes.add()
749749
assert isinstance(color, ColourRgb)
750750
color.name = attribute_name
@@ -782,34 +782,40 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
782782
def _execute(self, context):
783783
self.props = tool.Style.get_style_props()
784784
self.style = tool.Ifc.get().by_id(self.props.is_editing_style)
785+
prev_update_graph = self.props.update_graph
786+
self.props["update_graph"] = False
785787

786-
style_elements = tool.Style.get_style_elements(self.style)
787-
# NOTE: currently this operator is used to edit existing (and only existing) IfcSurfaceStyles
788-
# or new or existing IfcSurfaceStyle components (shading, etc)
789-
# which is kind of confusing.
790-
if self.props.is_editing_class == "IfcSurfaceStyle":
791-
self.surface_style = self.style
792-
else:
793-
self.surface_style = style_elements.get(self.props.is_editing_class, None)
794-
self.shading_style = style_elements.get("IfcSurfaceStyleShading", None)
795-
self.rendering_style = style_elements.get("IfcSurfaceStyleRendering", None)
796-
self.texture_style = style_elements.get("IfcSurfaceStyleWithTextures", None)
788+
try:
789+
style_elements = tool.Style.get_style_elements(self.style)
797790

798-
if self.surface_style:
799-
result = self.edit_existing_style()
800-
else:
801-
result = self.add_new_style()
791+
# NOTE: currently this operator is used to edit existing (and only existing) IfcSurfaceStyles
792+
# or new or existing IfcSurfaceStyle components (shading, etc)
793+
# which is kind of confusing.
794+
if self.props.is_editing_class == "IfcSurfaceStyle":
795+
self.surface_style = self.style
796+
else:
797+
self.surface_style = style_elements.get(self.props.is_editing_class, None)
798+
self.shading_style = style_elements.get("IfcSurfaceStyleShading", None)
799+
self.rendering_style = style_elements.get("IfcSurfaceStyleRendering", None)
800+
self.texture_style = style_elements.get("IfcSurfaceStyleWithTextures", None)
802801

803-
if result:
804-
return result
802+
if self.surface_style:
803+
result = self.edit_existing_style()
804+
else:
805+
result = self.add_new_style()
805806

806-
tool.Style.disable_editing()
807-
core.load_styles(tool.Style, style_type=self.props.style_type)
807+
if result:
808+
return result
808809

809-
# restore selected style type
810-
material = tool.Ifc.get_object(self.style)
811-
msprops = tool.Style.get_material_style_props(material)
812-
msprops.active_style_type = msprops.active_style_type
810+
tool.Style.disable_editing()
811+
core.load_styles(tool.Style, style_type=self.props.style_type)
812+
813+
# restore selected style type
814+
material = tool.Ifc.get_object(self.style)
815+
msprops = tool.Style.get_material_style_props(material)
816+
msprops.active_style_type = msprops.active_style_type
817+
finally:
818+
self.props["update_graph"] = prev_update_graph
813819

814820
def edit_existing_style(self) -> None:
815821
ifc_file = tool.Ifc.get()
@@ -1231,4 +1237,5 @@ def _execute(self, context):
12311237
surface_style = tool.Style.get_style_elements(style)[props.is_editing_class]
12321238
ifcopenshell.api.style.remove_surface_style(ifc_file, surface_style)
12331239
core.disable_editing_style(tool.Style)
1240+
core.load_styles(tool.Style, style_type=props.style_type)
12341241
return {"FINISHED"}

src/bonsai/bonsai/bim/module/style/prop.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ def get_value(self):
185185
# to fit blender.bim.helper.draw_attribute
186186
is_optional = False
187187
special_type = ""
188+
data_type = ""
189+
ifc_class = ""
190+
use_explorer_ui = False
191+
192+
@property
193+
def display_name(self):
194+
return self.name
188195

189196
def get_value_name(self, *args, **kwargs):
190197
return "color_value"

src/bonsai/bonsai/bim/module/style/ui.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,30 @@ def draw_surface_style_rendering(self):
176176
row.prop(self.props, "reflectance_method")
177177

178178
if self.props.reflectance_method not in ("PHYSICAL", "NOTDEFINED", "FLAT"):
179-
self.layout.label(text="Supported reflectance methods are:")
180-
self.layout.label(text="PHYSICAL / NOTDEFINED / FLAT")
179+
self.layout.label(
180+
text=f"{self.props.reflectance_method} will be skipped: only PHYSICAL / NOTDEFINED / FLAT are supported",
181+
icon="ERROR",
182+
)
183+
elif self.props.reflectance_method in ("PHYSICAL", "NOTDEFINED"):
184+
if self.props.specular_colour_class == "IfcColourRgb":
185+
self.layout.label(
186+
text="Metallic color is IFC-only in PHYSICAL/NOTDEFINED and does not affect Blender appearance",
187+
icon="ERROR",
188+
)
189+
elif self.props.reflectance_method == "FLAT":
190+
if self.props.diffuse_colour_class == "IfcNormalisedRatioMeasure":
191+
self.layout.label(
192+
text="Emissive ratio is IFC-only in FLAT Reflectance method and does not affect Blender appearance",
193+
icon="ERROR",
194+
)
195+
self.layout.label(
196+
text="Specular value is IFC-only in FLAT Reflectance method and does not affect Blender appearance",
197+
icon="ERROR",
198+
)
199+
self.layout.label(
200+
text="Highlight value is IFC-only in FLAT Reflectance method and does not affect Blender appearance",
201+
icon="ERROR",
202+
)
181203

182204
row = self.layout.row(align=True)
183205
row.label(text="Emissive" if self.props.reflectance_method == "FLAT" else "Diffuse")
@@ -232,6 +254,8 @@ def draw_surface_style_with_textures(self):
232254
row.operator("bim.add_surface_texture", text="", icon="ADD")
233255
if textures:
234256
self.layout.prop(self.props, "uv_mode")
257+
if self.props.uv_mode in ("Generated", "Camera"):
258+
self.layout.label(text="Not available in SOLID Mode", icon="INFO")
235259

236260
for i, texture in enumerate(textures):
237261
split = self.layout.split(factor=0.30, align=True)
@@ -244,6 +268,22 @@ def draw_surface_style_with_textures(self):
244268
op_clear = row.operator("bim.remove_texture_map", text="", icon="X")
245269
op_path.texture_map_index = op_clear.texture_map_index = i
246270

271+
reflectance = self.props.reflectance_method
272+
mode = texture.mode
273+
if reflectance == "FLAT":
274+
if mode != "EMISSIVE":
275+
self.layout.label(
276+
text=f"{mode} will be skipped: only EMISSIVE is supported for Render Reflectance FLAT",
277+
icon="ERROR",
278+
)
279+
elif reflectance in ("PHYSICAL", "NOTDEFINED"):
280+
_SUPPORTED = {"DIFFUSE", "NORMAL", "METALLICROUGHNESS", "EMISSIVE", "OCCLUSION"}
281+
if mode not in _SUPPORTED:
282+
self.layout.label(
283+
text=f"{mode} will be skipped: not supported for Render Reflectance PHYSICAL/NOTDEFINED",
284+
icon="ERROR",
285+
)
286+
247287
def draw_externally_defined_surface_style(self):
248288
row = self.layout.row()
249289
op = row.operator("bim.browse_external_style", icon="APPEND_BLEND", text="Append From Blend File")
@@ -252,10 +292,17 @@ def draw_externally_defined_surface_style(self):
252292
bonsai.bim.helper.draw_attributes(self.props.external_style_attributes, self.layout, enable_search=True)
253293

254294
def draw_refraction_surface_style(self):
295+
self.layout.label(
296+
text="Refraction values are IFC-only and do not affect Blender surface appearance",
297+
icon="ERROR",
298+
)
255299
bonsai.bim.helper.draw_attributes(self.props.refraction_style_attributes, self.layout, enable_search=True)
256-
row = self.layout.row(align=True)
257300

258301
def draw_lighting_surface_style(self):
302+
self.layout.label(
303+
text="Lighting values are IFC-only and do not affect Blender surface appearance",
304+
icon="ERROR",
305+
)
259306
bonsai.bim.helper.draw_attributes(self.props.lighting_style_colours, self.layout)
260307

261308
def draw_edit_ui(self, edit_label: str):

src/bonsai/bonsai/tool/loader.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def surface_texture_to_dict(cls, surface_texture):
189189
uv_mode = "Generated"
190190
elif coordinates.is_a("IfcTextureCoordinateGenerator") and coordinates.Mode == "COORD-EYE":
191191
uv_mode = "Camera"
192-
surface_texture["uv_mode"] = uv_mode or "Generated"
192+
surface_texture["uv_mode"] = uv_mode or "UV"
193193
return surface_texture
194194

195195
@classmethod
@@ -315,7 +315,7 @@ def get_image() -> Union[bpy.types.Image, None]:
315315
image_url = str(image_url)
316316
if is_relative and bpy.data.filepath:
317317
image_url = bpy.path.relpath(image_url)
318-
return bpy.data.images.load(image_url)
318+
return bpy.data.images.load(image_url, check_existing=True)
319319

320320
elif texture["type"] == "IfcBlobTexture":
321321
# https://blender.stackexchange.com/questions/173206/how-to-efficiently-convert-a-pil-image-to-bpy-types-image
@@ -472,12 +472,23 @@ def get_gltf_occlusion_output():
472472
print(f"{mode} Mode texture will be skipped.")
473473
continue
474474

475-
if (image := get_image) is None:
475+
if (image := get_image()) is None:
476476
continue
477477

478-
# remove RGB node from `create_surface_style_rendering`
479-
prev_node = bsdf.inputs[2].links[0].from_node
480-
blender_material.node_tree.nodes.remove(prev_node)
478+
# Replace whatever currently feeds the FLAT color input (RGB or previous texture chain).
479+
for link in list(bsdf.inputs[2].links):
480+
prev_node = link.from_node
481+
blender_material.node_tree.links.remove(link)
482+
if prev_node.type == "TEX_IMAGE":
483+
# Remove linked texture coordinate node if it's no longer used.
484+
for vec_link in list(prev_node.inputs["Vector"].links):
485+
coord_node = vec_link.from_node
486+
blender_material.node_tree.links.remove(vec_link)
487+
if coord_node.type == "TEX_COORD" and not any(o.links for o in coord_node.outputs):
488+
blender_material.node_tree.nodes.remove(coord_node)
489+
blender_material.node_tree.nodes.remove(prev_node)
490+
elif prev_node.type == "RGB":
491+
blender_material.node_tree.nodes.remove(prev_node)
481492

482493
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
483494
node.location = bsdf.location - Vector((200, 250))

0 commit comments

Comments
 (0)