This commit is contained in:
Andrej730
2025-07-21 11:26:15 +05:00
parent dcf8329b04
commit adfe56c777
6 changed files with 94 additions and 25 deletions
@@ -1886,12 +1886,12 @@ class LoadLinkedProject(bpy.types.Operator, ImportHelper):
print("Finished", time.time() - start)
return {"FINISHED"}
def process_occurrence(self, shape: ShapeElementType) -> None:
def process_occurrence(self, shape: W.TriangulationElement) -> None:
element = self.file.by_id(shape.id)
faces: tuple[int, ...] = shape.geometry.faces
verts: tuple[float, ...] = shape.geometry.verts
materials: tuple[W.style, ...] = shape.geometry.materials
material_ids: tuple[int, ...] = shape.geometry.material_ids
faces = shape.geometry.faces
verts = shape.geometry.verts
materials = shape.geometry.materials
material_ids = shape.geometry.material_ids
mat = ifcopenshell.util.shape.get_shape_matrix(shape)
@@ -1920,7 +1920,7 @@ class LoadLinkedProject(bpy.types.Operator, ImportHelper):
verts = geometry.verts
mesh["has_cartesian_point_offset"] = False
material_to_slot = {}
material_to_slot: dict[int, int] = {}
max_slot_index = 0
for i, material in enumerate(materials):
+2 -2
View File
@@ -39,8 +39,8 @@ class TesterData:
return bool(tool.Tester.report)
@classmethod
def specification(cls) -> list[ifctester.reporter.ResultsSpecification]:
def specification(cls) -> ifctester.reporter.ResultsSpecification:
if not tool.Tester.report:
return []
props = bpy.context.scene.IfcTesterProperties
props = tool.Tester.get_tester_props()
return tool.Tester.report[props.active_specification_index]
@@ -39,7 +39,7 @@ class ExecuteIfcTester(bpy.types.Operator):
@classmethod
def poll(cls, context):
props = context.scene.IfcTesterProperties
props = tool.Tester.get_tester_props()
if not props.should_load_from_memory and not props.ifc_files.single_file:
cls.poll_message_set("Select an IFC file or use 'load from memory' if it's loaded in Bonsai.")
return False
@@ -48,7 +48,7 @@ class ExecuteIfcTester(bpy.types.Operator):
return True
def execute(self, context):
props = context.scene.IfcTesterProperties
props = tool.Tester.get_tester_props()
props.specifications.clear()
@@ -69,7 +69,7 @@ class ExecuteIfcTester(bpy.types.Operator):
return {"FINISHED"}
def execute_tester(self, ifc_data: ifcopenshell.file, ifc_path: str, specs_path: str) -> Union[set[str], None]:
props = bpy.context.scene.IfcTesterProperties
props = tool.Tester.get_tester_props()
props.failed_entities.clear()
# No need for if-statement, just postponing lots of diffs.
@@ -132,7 +132,7 @@ class SelectRequirement(bpy.types.Operator):
req_index: bpy.props.IntProperty()
def execute(self, context):
props = context.scene.IfcTesterProperties
props = tool.Tester.get_tester_props()
report = tool.Tester.report
props.old_index = self.spec_index
failed_entities = report[self.spec_index]["requirements"][self.req_index]["failed_entities"]
@@ -169,7 +169,7 @@ class SelectFailedEntities(bpy.types.Operator):
req_index: bpy.props.IntProperty()
def execute(self, context):
props = context.scene.IfcTesterProperties
props = tool.Tester.get_tester_props()
report = tool.Tester.report
props.old_index = self.spec_index
failed_entities = report[self.spec_index]["requirements"][self.req_index]["failed_entities"]
+28 -2
View File
@@ -16,6 +16,9 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from typing import TYPE_CHECKING
import bpy
from bonsai.bim.module.tester.data import TesterData
from bonsai.bim.prop import StrProperty, MultipleFileSelect
from bpy.types import PropertyGroup
@@ -31,21 +34,29 @@ from bpy.props import (
)
def update_active_specification_index(self, context):
def update_active_specification_index(self: "IfcTesterProperties", context: bpy.types.Context) -> None:
TesterData.load()
class Specification(PropertyGroup):
name: StringProperty(name="Name")
description: StringProperty(name="Description")
status: BoolProperty(default=False, name="Status")
if TYPE_CHECKING:
description: str
status: bool
class FailedEntities(PropertyGroup):
ifc_id: IntProperty(name="IFC ID")
element: StringProperty(name="Element")
reason: StringProperty(name="Reason")
if TYPE_CHECKING:
ifc_id: int
element: str
reason: str
class IfcTesterProperties(PropertyGroup):
specs: PointerProperty(type=MultipleFileSelect)
@@ -66,3 +77,18 @@ class IfcTesterProperties(PropertyGroup):
failed_entities: CollectionProperty(name="FailedEntities", type=FailedEntities)
has_entities: BoolProperty(default=False, name="")
n_entities: IntProperty(name="", default=0)
if TYPE_CHECKING:
specs: MultipleFileSelect
ifc_files: MultipleFileSelect
should_load_from_memory: bool
generate_html_report: bool
generate_ods_report: bool
flag: bool
active_specification_index: int
old_index: int
active_failed_entity_index: int
specifications: bpy.types.bpy_prop_collection_idprop[Specification]
failed_entities: bpy.types.bpy_prop_collection_idprop[FailedEntities]
has_entities: bool
n_entities: int
+40 -9
View File
@@ -16,10 +16,22 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bonsai.tool as tool
from __future__ import annotations
from typing import TYPE_CHECKING
import bpy
from bpy.types import Panel, UIList
import bonsai.tool as tool
from bonsai.bim.module.tester.data import TesterData
if TYPE_CHECKING:
from bonsai.bim.module.tester.prop import (
FailedEntities,
IfcTesterProperties,
Specification,
)
class BIM_PT_tester(Panel):
bl_label = "IFC Tester"
@@ -34,8 +46,9 @@ class BIM_PT_tester(Panel):
if not TesterData.is_loaded:
TesterData.load()
assert self.layout
self.layout.use_property_split = True
props = context.scene.IfcTesterProperties
props = tool.Tester.get_tester_props()
if tool.Ifc.get():
row = self.layout.row()
@@ -68,16 +81,17 @@ class BIM_PT_tester(Panel):
"active_specification_index",
)
self.draw_editable_ui(context)
self.draw_editable_ui()
row = self.layout.row()
row.operator("bim.export_bcf", text="Export BCF", icon="EXPORT")
def draw_editable_ui(self, context):
props = context.scene.IfcTesterProperties
def draw_editable_ui(self) -> None:
props = tool.Tester.get_tester_props()
specification = TesterData.data["specification"]
n_requirements = len(specification["requirements"])
assert self.layout
row = self.layout.row()
row.label(
text=f'Passed: {specification["total_checks_pass"]}/{specification["total_checks"]} ({specification["percent_checks_pass"]}%)'
@@ -114,7 +128,16 @@ class BIM_PT_tester(Panel):
class BIM_UL_tester_specifications(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
def draw_item(
self,
context: bpy.types.Context,
layout: bpy.types.UILayout,
data: IfcTesterProperties,
item: Specification,
icon,
active_data,
active_propname,
) -> None:
if item:
row = layout.split(factor=0.3, align=True)
row.label(text=item.name, icon="CHECKMARK" if item.status else "CANCEL")
@@ -122,12 +145,20 @@ class BIM_UL_tester_specifications(UIList):
class BIM_UL_tester_failed_entities(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
props = context.scene.IfcTesterProperties
def draw_item(
self,
context: bpy.types.Context,
layout: bpy.types.UILayout,
data: IfcTesterProperties,
item: FailedEntities,
icon,
active_data,
active_propname,
) -> None:
if item:
row = layout.row(align=True)
row.label(text=item.element)
row.label(text=item.reason)
if props.should_load_from_memory:
if data.should_load_from_memory:
op = row.operator("bim.select_entity", text="", icon="RESTRICT_SELECT_OFF")
op.ifc_id = item.ifc_id
+13 -1
View File
@@ -16,11 +16,23 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import TYPE_CHECKING, Union
import bpy
import ifctester.ids
import ifctester.reporter
from typing import Union
if TYPE_CHECKING:
from bonsai.bim.module.tester.prop import IfcTesterProperties
class Tester:
specs: Union[ifctester.ids.Ids, None] = None
report: list[ifctester.reporter.ResultsSpecification] = []
@classmethod
def get_tester_props(cls) -> IfcTesterProperties:
assert (scene := bpy.context.scene)
return scene.IfcTesterProperties # pyright: ignore[reportAttributeAccessIssue]