mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
Extend ifc debug panel (#1924)
* Prevent searching for invalid ID in IFC debugger You can still input <= 0 IDs for debugging purposes But the field won't let you drag below ID = 1 Also changed default to 1 so it doesn't throw an error by default * Extend ops descriptions, labels and debug output * Use Operator property for selecting dense meshes * Prevent error if id has no geom representation * Use Poll operator and poll fail message * Debug op to select highest meshes by polygon percentile
This commit is contained in:
@@ -28,6 +28,7 @@ classes = (
|
|||||||
operator.CreateAllShapes,
|
operator.CreateAllShapes,
|
||||||
operator.CreateShapeFromStepId,
|
operator.CreateShapeFromStepId,
|
||||||
operator.SelectHighPolygonMeshes,
|
operator.SelectHighPolygonMeshes,
|
||||||
|
operator.SelectHighestPolygonMeshes,
|
||||||
operator.InspectFromStepId,
|
operator.InspectFromStepId,
|
||||||
operator.InspectFromObject,
|
operator.InspectFromObject,
|
||||||
operator.RewindInspector,
|
operator.RewindInspector,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from blenderbim.bim.ifc import IfcStore
|
|||||||
class PrintIfcFile(bpy.types.Operator):
|
class PrintIfcFile(bpy.types.Operator):
|
||||||
bl_idname = "bim.print_ifc_file"
|
bl_idname = "bim.print_ifc_file"
|
||||||
bl_label = "Print IFC File"
|
bl_label = "Print IFC File"
|
||||||
|
bl_description = "Prints the file contents in the system console.\nAccess it with Window > Toggle System Console"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
@@ -43,6 +44,7 @@ class PrintIfcFile(bpy.types.Operator):
|
|||||||
class PurgeIfcLinks(bpy.types.Operator):
|
class PurgeIfcLinks(bpy.types.Operator):
|
||||||
bl_idname = "bim.purge_ifc_links"
|
bl_idname = "bim.purge_ifc_links"
|
||||||
bl_label = "Purge IFC Links"
|
bl_label = "Purge IFC Links"
|
||||||
|
bl_description = "Purge all definitions and references from the file.\nWarning : Cannot be undone."
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
for obj in bpy.data.objects:
|
for obj in bpy.data.objects:
|
||||||
@@ -96,7 +98,8 @@ class ProfileImportIFC(bpy.types.Operator):
|
|||||||
|
|
||||||
class CreateAllShapes(bpy.types.Operator):
|
class CreateAllShapes(bpy.types.Operator):
|
||||||
bl_idname = "bim.create_all_shapes"
|
bl_idname = "bim.create_all_shapes"
|
||||||
bl_label = "Create All Shapes"
|
bl_label = "Test All Shapes"
|
||||||
|
bl_description = "Look for errors in all the shapes contained in the file"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
@@ -126,7 +129,7 @@ class CreateAllShapes(bpy.types.Operator):
|
|||||||
except:
|
except:
|
||||||
failures.append(element)
|
failures.append(element)
|
||||||
print("***** FAILURE *****")
|
print("***** FAILURE *****")
|
||||||
print("Failures:")
|
print(f"Failures: {len(failures)}")
|
||||||
for failure in failures:
|
for failure in failures:
|
||||||
print(failure)
|
print(failure)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -135,6 +138,7 @@ class CreateAllShapes(bpy.types.Operator):
|
|||||||
class CreateShapeFromStepId(bpy.types.Operator):
|
class CreateShapeFromStepId(bpy.types.Operator):
|
||||||
bl_idname = "bim.create_shape_from_step_id"
|
bl_idname = "bim.create_shape_from_step_id"
|
||||||
bl_label = "Create Shape From STEP ID"
|
bl_label = "Create Shape From STEP ID"
|
||||||
|
bl_description = "Recreate a mesh object from a STEP ID"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
should_include_curves: bpy.props.BoolProperty()
|
should_include_curves: bpy.props.BoolProperty()
|
||||||
|
|
||||||
@@ -154,9 +158,12 @@ class CreateShapeFromStepId(bpy.types.Operator):
|
|||||||
if self.should_include_curves:
|
if self.should_include_curves:
|
||||||
settings.set(settings.INCLUDE_CURVES, True)
|
settings.set(settings.INCLUDE_CURVES, True)
|
||||||
shape = ifcopenshell.geom.create_shape(settings, element)
|
shape = ifcopenshell.geom.create_shape(settings, element)
|
||||||
ifc_importer = import_ifc.IfcImporter(self.ifc_import_settings)
|
if shape:
|
||||||
ifc_importer.file = self.file
|
ifc_importer = import_ifc.IfcImporter(self.ifc_import_settings)
|
||||||
mesh = ifc_importer.create_mesh(element, shape)
|
ifc_importer.file = self.file
|
||||||
|
mesh = ifc_importer.create_mesh(element, shape)
|
||||||
|
else:
|
||||||
|
mesh = None
|
||||||
obj = bpy.data.objects.new("Debug", mesh)
|
obj = bpy.data.objects.new("Debug", mesh)
|
||||||
context.scene.collection.objects.link(obj)
|
context.scene.collection.objects.link(obj)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -165,20 +172,37 @@ class CreateShapeFromStepId(bpy.types.Operator):
|
|||||||
class SelectHighPolygonMeshes(bpy.types.Operator):
|
class SelectHighPolygonMeshes(bpy.types.Operator):
|
||||||
bl_idname = "bim.select_high_polygon_meshes"
|
bl_idname = "bim.select_high_polygon_meshes"
|
||||||
bl_label = "Select High Polygon Meshes"
|
bl_label = "Select High Polygon Meshes"
|
||||||
|
bl_description = "Select objects containing more polygons than the specified number"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
threshold: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
[
|
for obj in context.view_layer.objects:
|
||||||
o.select_set(True)
|
if obj.type == "MESH" and len(obj.data.polygons) > self.threshold:
|
||||||
for o in context.view_layer.objects
|
obj.select_set(True)
|
||||||
if o.type == "MESH" and len(o.data.polygons) > context.scene.BIMDebugProperties.number_of_polygons
|
return {"FINISHED"}
|
||||||
]
|
|
||||||
|
|
||||||
|
class SelectHighestPolygonMeshes(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.select_highest_polygon_meshes"
|
||||||
|
bl_label = "Select Highest Polygon Meshes"
|
||||||
|
bl_description = "Select objects with a number of polygons superior to the specified percentile"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
percentile: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
objects = [obj for obj in context.view_layer.objects if obj.type == "MESH"]
|
||||||
|
if objects:
|
||||||
|
percentile = len(max(objects, key=lambda o: len(o.data.polygons)).data.polygons) * self.percentile / 100
|
||||||
|
print(f"Selected all Meshes with more than {int(percentile)} polygons")
|
||||||
|
[obj.select_set(True) for obj in objects if len(obj.data.polygons) > percentile]
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class RewindInspector(bpy.types.Operator):
|
class RewindInspector(bpy.types.Operator):
|
||||||
bl_idname = "bim.rewind_inspector"
|
bl_idname = "bim.rewind_inspector"
|
||||||
bl_label = "Rewind Inspector"
|
bl_label = "Rewind Inspector"
|
||||||
|
bl_description = "Rewind the Inspector to the previously inspected element"
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMDebugProperties
|
props = context.scene.BIMDebugProperties
|
||||||
@@ -195,6 +219,7 @@ class RewindInspector(bpy.types.Operator):
|
|||||||
class InspectFromStepId(bpy.types.Operator):
|
class InspectFromStepId(bpy.types.Operator):
|
||||||
bl_idname = "bim.inspect_from_step_id"
|
bl_idname = "bim.inspect_from_step_id"
|
||||||
bl_label = "Inspect From STEP ID"
|
bl_label = "Inspect From STEP ID"
|
||||||
|
bl_description = "Inspect the attributes and references by looking up the specified STEP ID"
|
||||||
step_id: bpy.props.IntProperty()
|
step_id: bpy.props.IntProperty()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -245,12 +270,21 @@ class InspectFromStepId(bpy.types.Operator):
|
|||||||
class InspectFromObject(bpy.types.Operator):
|
class InspectFromObject(bpy.types.Operator):
|
||||||
bl_idname = "bim.inspect_from_object"
|
bl_idname = "bim.inspect_from_object"
|
||||||
bl_label = "Inspect From Object"
|
bl_label = "Inspect From Object"
|
||||||
|
bl_description = "Inspect the Active Object's attributes and references"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
if not context.active_object:
|
||||||
|
if bpy.app.version >= (3, 0, 0):
|
||||||
|
cls.poll_message_set("No Active Object")
|
||||||
|
elif not context.active_object.BIMObjectProperties.ifc_definition_id:
|
||||||
|
if bpy.app.version >= (3, 0, 0):
|
||||||
|
cls.poll_message_set("Active Object doesn't have an IFC definition")
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
ifc_definition_id = context.active_object.BIMObjectProperties.ifc_definition_id
|
bpy.ops.bim.inspect_from_step_id(step_id=context.active_object.BIMObjectProperties.ifc_definition_id)
|
||||||
if not ifc_definition_id:
|
|
||||||
return {"FINISHED"}
|
|
||||||
bpy.ops.bim.inspect_from_step_id(step_id=ifc_definition_id)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ from bpy.props import (
|
|||||||
class BIMDebugProperties(PropertyGroup):
|
class BIMDebugProperties(PropertyGroup):
|
||||||
step_id: IntProperty(name="STEP ID")
|
step_id: IntProperty(name="STEP ID")
|
||||||
number_of_polygons: IntProperty(name="Number of Polygons", min=0)
|
number_of_polygons: IntProperty(name="Number of Polygons", min=0)
|
||||||
active_step_id: IntProperty(name="STEP ID")
|
percentile_of_polygons: IntProperty(name="Percentile of Polygons", min=0, max=100, default=90, subtype="PERCENTAGE")
|
||||||
|
active_step_id: IntProperty(name="STEP ID", default=1, soft_min=1)
|
||||||
step_id_breadcrumb: CollectionProperty(name="STEP ID Breadcrumb", type=StrProperty)
|
step_id_breadcrumb: CollectionProperty(name="STEP ID Breadcrumb", type=StrProperty)
|
||||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||||
inverse_attributes: CollectionProperty(name="Inverse Attributes", type=Attribute)
|
inverse_attributes: CollectionProperty(name="Inverse Attributes", type=Attribute)
|
||||||
|
|||||||
@@ -56,8 +56,11 @@ class BIM_PT_debug(Panel):
|
|||||||
row.prop(props, "step_id", text="")
|
row.prop(props, "step_id", text="")
|
||||||
|
|
||||||
row = layout.split(factor=0.7, align=True)
|
row = layout.split(factor=0.7, align=True)
|
||||||
row.operator("bim.select_high_polygon_meshes")
|
row.operator("bim.select_high_polygon_meshes").threshold = context.scene.BIMDebugProperties.number_of_polygons
|
||||||
row.prop(props, "number_of_polygons", text="")
|
row.prop(props, "number_of_polygons", text="")
|
||||||
|
row = layout.split(factor=0.7, align=True)
|
||||||
|
row.operator("bim.select_highest_polygon_meshes").percentile = context.scene.BIMDebugProperties.percentile_of_polygons
|
||||||
|
row.prop(props, "percentile_of_polygons", text="")
|
||||||
|
|
||||||
layout.label(text="Inspector:")
|
layout.label(text="Inspector:")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user