mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 06:39:13 +00:00
Merge pull request #8014 from falken10vdl/surface-style-small-fixes
Surface styles fixes and message warnings
This commit is contained in:
@@ -744,7 +744,7 @@ class EnableEditingSurfaceStyle(bpy.types.Operator):
|
|||||||
if self.ifc_class == "IfcSurfaceStyleLighting":
|
if self.ifc_class == "IfcSurfaceStyleLighting":
|
||||||
|
|
||||||
def callback(attribute_name: str, _: object, data: dict[str, Any]) -> None:
|
def callback(attribute_name: str, _: object, data: dict[str, Any]) -> None:
|
||||||
assert attributes
|
assert attributes is not None
|
||||||
color = attributes.add()
|
color = attributes.add()
|
||||||
assert isinstance(color, ColourRgb)
|
assert isinstance(color, ColourRgb)
|
||||||
color.name = attribute_name
|
color.name = attribute_name
|
||||||
@@ -782,34 +782,40 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.props = tool.Style.get_style_props()
|
self.props = tool.Style.get_style_props()
|
||||||
self.style = tool.Ifc.get().by_id(self.props.is_editing_style)
|
self.style = tool.Ifc.get().by_id(self.props.is_editing_style)
|
||||||
|
prev_update_graph = self.props.update_graph
|
||||||
|
self.props["update_graph"] = False
|
||||||
|
|
||||||
style_elements = tool.Style.get_style_elements(self.style)
|
try:
|
||||||
# NOTE: currently this operator is used to edit existing (and only existing) IfcSurfaceStyles
|
style_elements = tool.Style.get_style_elements(self.style)
|
||||||
# or new or existing IfcSurfaceStyle components (shading, etc)
|
|
||||||
# which is kind of confusing.
|
|
||||||
if self.props.is_editing_class == "IfcSurfaceStyle":
|
|
||||||
self.surface_style = self.style
|
|
||||||
else:
|
|
||||||
self.surface_style = style_elements.get(self.props.is_editing_class, None)
|
|
||||||
self.shading_style = style_elements.get("IfcSurfaceStyleShading", None)
|
|
||||||
self.rendering_style = style_elements.get("IfcSurfaceStyleRendering", None)
|
|
||||||
self.texture_style = style_elements.get("IfcSurfaceStyleWithTextures", None)
|
|
||||||
|
|
||||||
if self.surface_style:
|
# NOTE: currently this operator is used to edit existing (and only existing) IfcSurfaceStyles
|
||||||
result = self.edit_existing_style()
|
# or new or existing IfcSurfaceStyle components (shading, etc)
|
||||||
else:
|
# which is kind of confusing.
|
||||||
result = self.add_new_style()
|
if self.props.is_editing_class == "IfcSurfaceStyle":
|
||||||
|
self.surface_style = self.style
|
||||||
|
else:
|
||||||
|
self.surface_style = style_elements.get(self.props.is_editing_class, None)
|
||||||
|
self.shading_style = style_elements.get("IfcSurfaceStyleShading", None)
|
||||||
|
self.rendering_style = style_elements.get("IfcSurfaceStyleRendering", None)
|
||||||
|
self.texture_style = style_elements.get("IfcSurfaceStyleWithTextures", None)
|
||||||
|
|
||||||
if result:
|
if self.surface_style:
|
||||||
return result
|
result = self.edit_existing_style()
|
||||||
|
else:
|
||||||
|
result = self.add_new_style()
|
||||||
|
|
||||||
tool.Style.disable_editing()
|
if result:
|
||||||
core.load_styles(tool.Style, style_type=self.props.style_type)
|
return result
|
||||||
|
|
||||||
# restore selected style type
|
tool.Style.disable_editing()
|
||||||
material = tool.Ifc.get_object(self.style)
|
core.load_styles(tool.Style, style_type=self.props.style_type)
|
||||||
msprops = tool.Style.get_material_style_props(material)
|
|
||||||
msprops.active_style_type = msprops.active_style_type
|
# restore selected style type
|
||||||
|
material = tool.Ifc.get_object(self.style)
|
||||||
|
msprops = tool.Style.get_material_style_props(material)
|
||||||
|
msprops.active_style_type = msprops.active_style_type
|
||||||
|
finally:
|
||||||
|
self.props["update_graph"] = prev_update_graph
|
||||||
|
|
||||||
def edit_existing_style(self) -> None:
|
def edit_existing_style(self) -> None:
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
@@ -1231,4 +1237,5 @@ class RemoveSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
surface_style = tool.Style.get_style_elements(style)[props.is_editing_class]
|
surface_style = tool.Style.get_style_elements(style)[props.is_editing_class]
|
||||||
ifcopenshell.api.style.remove_surface_style(ifc_file, surface_style)
|
ifcopenshell.api.style.remove_surface_style(ifc_file, surface_style)
|
||||||
core.disable_editing_style(tool.Style)
|
core.disable_editing_style(tool.Style)
|
||||||
|
core.load_styles(tool.Style, style_type=props.style_type)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -185,6 +185,13 @@ class ColourRgb(PropertyGroup):
|
|||||||
# to fit blender.bim.helper.draw_attribute
|
# to fit blender.bim.helper.draw_attribute
|
||||||
is_optional = False
|
is_optional = False
|
||||||
special_type = ""
|
special_type = ""
|
||||||
|
data_type = ""
|
||||||
|
ifc_class = ""
|
||||||
|
use_explorer_ui = False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display_name(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def get_value_name(self, *args, **kwargs):
|
def get_value_name(self, *args, **kwargs):
|
||||||
return "color_value"
|
return "color_value"
|
||||||
|
|||||||
@@ -176,8 +176,30 @@ class BIM_PT_styles(Panel):
|
|||||||
row.prop(self.props, "reflectance_method")
|
row.prop(self.props, "reflectance_method")
|
||||||
|
|
||||||
if self.props.reflectance_method not in ("PHYSICAL", "NOTDEFINED", "FLAT"):
|
if self.props.reflectance_method not in ("PHYSICAL", "NOTDEFINED", "FLAT"):
|
||||||
self.layout.label(text="Supported reflectance methods are:")
|
self.layout.label(
|
||||||
self.layout.label(text="PHYSICAL / NOTDEFINED / FLAT")
|
text=f"{self.props.reflectance_method} will be skipped: only PHYSICAL / NOTDEFINED / FLAT are supported",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
|
elif self.props.reflectance_method in ("PHYSICAL", "NOTDEFINED"):
|
||||||
|
if self.props.specular_colour_class == "IfcColourRgb":
|
||||||
|
self.layout.label(
|
||||||
|
text="Metallic color is IFC-only in PHYSICAL/NOTDEFINED and does not affect Blender appearance",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
|
elif self.props.reflectance_method == "FLAT":
|
||||||
|
if self.props.diffuse_colour_class == "IfcNormalisedRatioMeasure":
|
||||||
|
self.layout.label(
|
||||||
|
text="Emissive ratio is IFC-only in FLAT Reflectance method and does not affect Blender appearance",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
|
self.layout.label(
|
||||||
|
text="Specular value is IFC-only in FLAT Reflectance method and does not affect Blender appearance",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
|
self.layout.label(
|
||||||
|
text="Highlight value is IFC-only in FLAT Reflectance method and does not affect Blender appearance",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.label(text="Emissive" if self.props.reflectance_method == "FLAT" else "Diffuse")
|
row.label(text="Emissive" if self.props.reflectance_method == "FLAT" else "Diffuse")
|
||||||
@@ -232,6 +254,8 @@ class BIM_PT_styles(Panel):
|
|||||||
row.operator("bim.add_surface_texture", text="", icon="ADD")
|
row.operator("bim.add_surface_texture", text="", icon="ADD")
|
||||||
if textures:
|
if textures:
|
||||||
self.layout.prop(self.props, "uv_mode")
|
self.layout.prop(self.props, "uv_mode")
|
||||||
|
if self.props.uv_mode in ("Generated", "Camera"):
|
||||||
|
self.layout.label(text="Not available in SOLID Mode", icon="INFO")
|
||||||
|
|
||||||
for i, texture in enumerate(textures):
|
for i, texture in enumerate(textures):
|
||||||
split = self.layout.split(factor=0.30, align=True)
|
split = self.layout.split(factor=0.30, align=True)
|
||||||
@@ -244,6 +268,22 @@ class BIM_PT_styles(Panel):
|
|||||||
op_clear = row.operator("bim.remove_texture_map", text="", icon="X")
|
op_clear = row.operator("bim.remove_texture_map", text="", icon="X")
|
||||||
op_path.texture_map_index = op_clear.texture_map_index = i
|
op_path.texture_map_index = op_clear.texture_map_index = i
|
||||||
|
|
||||||
|
reflectance = self.props.reflectance_method
|
||||||
|
mode = texture.mode
|
||||||
|
if reflectance == "FLAT":
|
||||||
|
if mode != "EMISSIVE":
|
||||||
|
self.layout.label(
|
||||||
|
text=f"{mode} will be skipped: only EMISSIVE is supported for Render Reflectance FLAT",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
|
elif reflectance in ("PHYSICAL", "NOTDEFINED"):
|
||||||
|
_SUPPORTED = {"DIFFUSE", "NORMAL", "METALLICROUGHNESS", "EMISSIVE", "OCCLUSION"}
|
||||||
|
if mode not in _SUPPORTED:
|
||||||
|
self.layout.label(
|
||||||
|
text=f"{mode} will be skipped: not supported for Render Reflectance PHYSICAL/NOTDEFINED",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
|
|
||||||
def draw_externally_defined_surface_style(self):
|
def draw_externally_defined_surface_style(self):
|
||||||
row = self.layout.row()
|
row = self.layout.row()
|
||||||
op = row.operator("bim.browse_external_style", icon="APPEND_BLEND", text="Append From Blend File")
|
op = row.operator("bim.browse_external_style", icon="APPEND_BLEND", text="Append From Blend File")
|
||||||
@@ -252,10 +292,17 @@ class BIM_PT_styles(Panel):
|
|||||||
bonsai.bim.helper.draw_attributes(self.props.external_style_attributes, self.layout, enable_search=True)
|
bonsai.bim.helper.draw_attributes(self.props.external_style_attributes, self.layout, enable_search=True)
|
||||||
|
|
||||||
def draw_refraction_surface_style(self):
|
def draw_refraction_surface_style(self):
|
||||||
|
self.layout.label(
|
||||||
|
text="Refraction values are IFC-only and do not affect Blender surface appearance",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
bonsai.bim.helper.draw_attributes(self.props.refraction_style_attributes, self.layout, enable_search=True)
|
bonsai.bim.helper.draw_attributes(self.props.refraction_style_attributes, self.layout, enable_search=True)
|
||||||
row = self.layout.row(align=True)
|
|
||||||
|
|
||||||
def draw_lighting_surface_style(self):
|
def draw_lighting_surface_style(self):
|
||||||
|
self.layout.label(
|
||||||
|
text="Lighting values are IFC-only and do not affect Blender surface appearance",
|
||||||
|
icon="ERROR",
|
||||||
|
)
|
||||||
bonsai.bim.helper.draw_attributes(self.props.lighting_style_colours, self.layout)
|
bonsai.bim.helper.draw_attributes(self.props.lighting_style_colours, self.layout)
|
||||||
|
|
||||||
def draw_edit_ui(self, edit_label: str):
|
def draw_edit_ui(self, edit_label: str):
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ class Loader(bonsai.core.tool.Loader):
|
|||||||
uv_mode = "Generated"
|
uv_mode = "Generated"
|
||||||
elif coordinates.is_a("IfcTextureCoordinateGenerator") and coordinates.Mode == "COORD-EYE":
|
elif coordinates.is_a("IfcTextureCoordinateGenerator") and coordinates.Mode == "COORD-EYE":
|
||||||
uv_mode = "Camera"
|
uv_mode = "Camera"
|
||||||
surface_texture["uv_mode"] = uv_mode or "Generated"
|
surface_texture["uv_mode"] = uv_mode or "UV"
|
||||||
return surface_texture
|
return surface_texture
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -315,7 +315,7 @@ class Loader(bonsai.core.tool.Loader):
|
|||||||
image_url = str(image_url)
|
image_url = str(image_url)
|
||||||
if is_relative and bpy.data.filepath:
|
if is_relative and bpy.data.filepath:
|
||||||
image_url = bpy.path.relpath(image_url)
|
image_url = bpy.path.relpath(image_url)
|
||||||
return bpy.data.images.load(image_url)
|
return bpy.data.images.load(image_url, check_existing=True)
|
||||||
|
|
||||||
elif texture["type"] == "IfcBlobTexture":
|
elif texture["type"] == "IfcBlobTexture":
|
||||||
# https://blender.stackexchange.com/questions/173206/how-to-efficiently-convert-a-pil-image-to-bpy-types-image
|
# https://blender.stackexchange.com/questions/173206/how-to-efficiently-convert-a-pil-image-to-bpy-types-image
|
||||||
@@ -472,12 +472,23 @@ class Loader(bonsai.core.tool.Loader):
|
|||||||
print(f"{mode} Mode texture will be skipped.")
|
print(f"{mode} Mode texture will be skipped.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (image := get_image) is None:
|
if (image := get_image()) is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# remove RGB node from `create_surface_style_rendering`
|
# Replace whatever currently feeds the FLAT color input (RGB or previous texture chain).
|
||||||
prev_node = bsdf.inputs[2].links[0].from_node
|
for link in list(bsdf.inputs[2].links):
|
||||||
blender_material.node_tree.nodes.remove(prev_node)
|
prev_node = link.from_node
|
||||||
|
blender_material.node_tree.links.remove(link)
|
||||||
|
if prev_node.type == "TEX_IMAGE":
|
||||||
|
# Remove linked texture coordinate node if it's no longer used.
|
||||||
|
for vec_link in list(prev_node.inputs["Vector"].links):
|
||||||
|
coord_node = vec_link.from_node
|
||||||
|
blender_material.node_tree.links.remove(vec_link)
|
||||||
|
if coord_node.type == "TEX_COORD" and not any(o.links for o in coord_node.outputs):
|
||||||
|
blender_material.node_tree.nodes.remove(coord_node)
|
||||||
|
blender_material.node_tree.nodes.remove(prev_node)
|
||||||
|
elif prev_node.type == "RGB":
|
||||||
|
blender_material.node_tree.nodes.remove(prev_node)
|
||||||
|
|
||||||
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||||
node.location = bsdf.location - Vector((200, 250))
|
node.location = bsdf.location - Vector((200, 250))
|
||||||
|
|||||||
Reference in New Issue
Block a user