mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 04:37:56 +00:00
Add instructions to IFCTester in Blender (#7195)
* add instructions to blender ui * add requirement instructions to html * black .
This commit is contained in:
@@ -484,6 +484,7 @@ class SelectRequirement(bpy.types.Operator):
|
|||||||
props.n_entities = len(failed_entities)
|
props.n_entities = len(failed_entities)
|
||||||
props.has_entities = True if props.n_entities > 0 else False
|
props.has_entities = True if props.n_entities > 0 else False
|
||||||
props.failed_entities.clear()
|
props.failed_entities.clear()
|
||||||
|
props.active_requirement_index = self.req_index
|
||||||
|
|
||||||
for e in failed_entities:
|
for e in failed_entities:
|
||||||
new_entity = props.failed_entities.add()
|
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())
|
generate_ods_report: BoolProperty(default=False, name="Generate ODS report", options=set())
|
||||||
flag: BoolProperty(default=False, name="Flag Failed Entities", 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_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)
|
old_index: IntProperty(name="", default=0)
|
||||||
active_failed_entity_index: IntProperty(name="Active Failed Entity Index")
|
active_failed_entity_index: IntProperty(name="Active Failed Entity Index")
|
||||||
specifications: CollectionProperty(name="Specifications", type=Specification)
|
specifications: CollectionProperty(name="Specifications", type=Specification)
|
||||||
@@ -89,6 +91,7 @@ class IfcTesterProperties(PropertyGroup):
|
|||||||
generate_ods_report: bool
|
generate_ods_report: bool
|
||||||
flag: bool
|
flag: bool
|
||||||
active_specification_index: int
|
active_specification_index: int
|
||||||
|
active_requirement_index: int
|
||||||
old_index: int
|
old_index: int
|
||||||
active_failed_entity_index: int
|
active_failed_entity_index: int
|
||||||
specifications: bpy.types.bpy_prop_collection_idprop[Specification]
|
specifications: bpy.types.bpy_prop_collection_idprop[Specification]
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from bonsai.bim.ui import draw_multiline_text
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.types import Panel, UIList
|
from bpy.types import Panel, UIList
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
@@ -95,11 +97,11 @@ class BIM_PT_tester(Panel):
|
|||||||
"active_specification_index",
|
"active_specification_index",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.draw_editable_ui()
|
self.draw_editable_ui(context)
|
||||||
row = self.layout.row()
|
row = self.layout.row()
|
||||||
row.operator("bim.export_bcf", text="Export BCF", icon="EXPORT")
|
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()
|
props = tool.Tester.get_tester_props()
|
||||||
specification = TesterData.data["specification"]
|
specification = TesterData.data["specification"]
|
||||||
|
|
||||||
@@ -110,6 +112,13 @@ class BIM_PT_tester(Panel):
|
|||||||
row.label(
|
row.label(
|
||||||
text=f'Passed: {specification["total_checks_pass"]}/{specification["total_checks"]} ({specification["percent_checks_pass"]}%)'
|
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 = self.layout.row()
|
||||||
row.label(text=f"Requirements ({n_requirements}):")
|
row.label(text=f"Requirements ({n_requirements}):")
|
||||||
if props.flag:
|
if props.flag:
|
||||||
@@ -132,6 +141,16 @@ class BIM_PT_tester(Panel):
|
|||||||
and props.n_entities > 0
|
and props.n_entities > 0
|
||||||
and len(props.failed_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 = self.layout.row()
|
||||||
row.label(text=f"Failed entities [{props.n_entities}]:")
|
row.label(text=f"Failed entities [{props.n_entities}]:")
|
||||||
self.layout.template_list(
|
self.layout.template_list(
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ from bonsai.bim.module.bsdd.prop import BIMBSDDProperties, BSDDProperty
|
|||||||
from bonsai.bim.module.pset.prop import IfcProperty
|
from bonsai.bim.module.pset.prop import IfcProperty
|
||||||
from typing import Optional, TYPE_CHECKING, Literal
|
from typing import Optional, TYPE_CHECKING, Literal
|
||||||
from natsort import natsorted
|
from natsort import natsorted
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -1491,6 +1492,31 @@ def draw_custom_context_menu(self: bpy.types.Menu, context: bpy.types.Context) -
|
|||||||
url_op.uri = url
|
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):
|
class BIM_PT_decorators_overlay(Panel):
|
||||||
bl_space_type = "VIEW_3D"
|
bl_space_type = "VIEW_3D"
|
||||||
bl_region_type = "HEADER"
|
bl_region_type = "HEADER"
|
||||||
|
|||||||
@@ -459,7 +459,8 @@ class Html(Json):
|
|||||||
requirement["total_passed_entities"] = total_passed_entities
|
requirement["total_passed_entities"] = total_passed_entities
|
||||||
requirement["total_omitted_passes"] = total_passed_entities - self.entity_limit
|
requirement["total_omitted_passes"] = total_passed_entities - self.entity_limit
|
||||||
requirement["has_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):
|
def limit_entities(self, entities):
|
||||||
if len(entities) > self.entity_limit:
|
if len(entities) > self.entity_limit:
|
||||||
if entities[0]["element_type"]:
|
if entities[0]["element_type"]:
|
||||||
|
|||||||
@@ -157,6 +157,14 @@
|
|||||||
<summary>
|
<summary>
|
||||||
{{description}}
|
{{description}}
|
||||||
</summary>
|
</summary>
|
||||||
|
{{#instructions}}
|
||||||
|
<div class="instructions">
|
||||||
|
<p>
|
||||||
|
<strong>Instructions</strong>
|
||||||
|
</p>
|
||||||
|
{{instructions}}
|
||||||
|
</div>
|
||||||
|
{{/instructions}}
|
||||||
{{#total_ckecks}}
|
{{#total_ckecks}}
|
||||||
<table class="skipped">
|
<table class="skipped">
|
||||||
<thead>
|
<thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user