Add instructions to IFCTester in Blender (#7195)

* add instructions to blender ui

* add requirement instructions to html

* black .
This commit is contained in:
Christoph Mellüh
2025-10-06 06:48:45 +02:00
committed by GitHub
parent f31df307c6
commit 16fd614886
6 changed files with 61 additions and 3 deletions
@@ -484,6 +484,7 @@ class SelectRequirement(bpy.types.Operator):
props.n_entities = len(failed_entities)
props.has_entities = True if props.n_entities > 0 else False
props.failed_entities.clear()
props.active_requirement_index = self.req_index
for e in failed_entities:
new_entity = props.failed_entities.add()
@@ -71,6 +71,8 @@ class IfcTesterProperties(PropertyGroup):
generate_ods_report: BoolProperty(default=False, name="Generate ODS report", options=set())
flag: BoolProperty(default=False, name="Flag Failed Entities", options=set())
active_specification_index: IntProperty(name="Active Specification Index", update=update_active_specification_index)
active_requirement_index: IntProperty(name="Active Requirement Index")
old_index: IntProperty(name="", default=0)
active_failed_entity_index: IntProperty(name="Active Failed Entity Index")
specifications: CollectionProperty(name="Specifications", type=Specification)
@@ -89,6 +91,7 @@ class IfcTesterProperties(PropertyGroup):
generate_ods_report: bool
flag: bool
active_specification_index: int
active_requirement_index: int
old_index: int
active_failed_entity_index: int
specifications: bpy.types.bpy_prop_collection_idprop[Specification]
+21 -2
View File
@@ -20,6 +20,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from bonsai.bim.ui import draw_multiline_text
import bpy
from bpy.types import Panel, UIList
import bonsai.tool as tool
@@ -95,11 +97,11 @@ class BIM_PT_tester(Panel):
"active_specification_index",
)
self.draw_editable_ui()
self.draw_editable_ui(context)
row = self.layout.row()
row.operator("bim.export_bcf", text="Export BCF", icon="EXPORT")
def draw_editable_ui(self) -> None:
def draw_editable_ui(self, context: bpy.types.Context) -> None:
props = tool.Tester.get_tester_props()
specification = TesterData.data["specification"]
@@ -110,6 +112,13 @@ class BIM_PT_tester(Panel):
row.label(
text=f'Passed: {specification["total_checks_pass"]}/{specification["total_checks"]} ({specification["percent_checks_pass"]}%)'
)
row = self.layout.row()
if specification.get("instructions"):
row.label(text="Instructions:")
box = self.layout.box()
column = box.column(align=True)
draw_multiline_text(column, specification.get("instructions"), context=context)
row = self.layout.row()
row.label(text=f"Requirements ({n_requirements}):")
if props.flag:
@@ -132,6 +141,16 @@ class BIM_PT_tester(Panel):
and props.n_entities > 0
and len(props.failed_entities) > 0
):
requirement = specification["requirements"][props.active_requirement_index]
metadata = requirement.get("metadata")
if metadata and metadata.get("@instructions"):
row = self.layout.row()
row.label(text="Instructions:")
box = self.layout.box()
column = box.column(align=True)
draw_multiline_text(column, metadata.get("@instructions"), context=context)
row = self.layout.row()
row.label(text=f"Failed entities [{props.n_entities}]:")
self.layout.template_list(
+26
View File
@@ -40,6 +40,7 @@ from bonsai.bim.module.bsdd.prop import BIMBSDDProperties, BSDDProperty
from bonsai.bim.module.pset.prop import IfcProperty
from typing import Optional, TYPE_CHECKING, Literal
from natsort import natsorted
import textwrap
if TYPE_CHECKING:
@@ -1491,6 +1492,31 @@ def draw_custom_context_menu(self: bpy.types.Menu, context: bpy.types.Context) -
url_op.uri = url
def draw_multiline_text(
layout: bpy.types.UILayout,
text: str,
*,
context: bpy.types.Context | None = None,
) -> None:
"""Render a read-only text box that wraps long text."""
assert layout
region_width = 200
if context and context.region:
region_width = context.region.width
approximate_char_width = 7 # Empirical average width for Blender UI font (px)
wrap_width = max(20, int(region_width / approximate_char_width))
for paragraph in text.splitlines():
if not paragraph:
layout.label(text="")
continue
for line in textwrap.wrap(paragraph, width=wrap_width):
layout.label(text=line)
class BIM_PT_decorators_overlay(Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "HEADER"
+2 -1
View File
@@ -459,7 +459,8 @@ class Html(Json):
requirement["total_passed_entities"] = total_passed_entities
requirement["total_omitted_passes"] = total_passed_entities - self.entity_limit
requirement["has_omitted_passes"] = total_passed_entities > self.entity_limit
requirement["instructions"] = requirement["metadata"].get("@instructions")
def limit_entities(self, entities):
if len(entities) > self.entity_limit:
if entities[0]["element_type"]:
@@ -157,6 +157,14 @@
<summary>
{{description}}
</summary>
{{#instructions}}
<div class="instructions">
<p>
<strong>Instructions</strong>
</p>
{{instructions}}
</div>
{{/instructions}}
{{#total_ckecks}}
<table class="skipped">
<thead>