mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
New UI to create, manage, and run clash sets within BlenderBIM Add-on
This commit is contained in:
@@ -96,6 +96,11 @@ if bpy is not None:
|
||||
operator.OpenView,
|
||||
operator.ActivateView,
|
||||
operator.ExecuteIfcDiff,
|
||||
operator.AddClashSet,
|
||||
operator.RemoveClashSet,
|
||||
operator.AddClashSource,
|
||||
operator.RemoveClashSource,
|
||||
operator.SelectClashSource,
|
||||
operator.ExecuteIfcClash,
|
||||
operator.AssignContext,
|
||||
operator.SwitchContext,
|
||||
@@ -138,6 +143,8 @@ if bpy is not None:
|
||||
prop.PropertyTemplate,
|
||||
prop.DocumentInformation,
|
||||
prop.DocumentReference,
|
||||
prop.ClashSource,
|
||||
prop.ClashSet,
|
||||
prop.BcfTopic,
|
||||
prop.BcfTopicLabel,
|
||||
prop.BcfTopicFile,
|
||||
@@ -186,6 +193,7 @@ if bpy is not None:
|
||||
ui.BIM_PT_documents,
|
||||
ui.BIM_PT_camera,
|
||||
ui.BIM_PT_text,
|
||||
ui.BIM_UL_clash_sets,
|
||||
ui.BIM_UL_document_information,
|
||||
ui.BIM_UL_document_references,
|
||||
ui.BIM_UL_topics,
|
||||
|
||||
@@ -1153,6 +1153,67 @@ class ExecuteIfcDiff(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddClashSet(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_clash_set'
|
||||
bl_label = 'Add Clash Set'
|
||||
|
||||
def execute(self, context):
|
||||
new = bpy.context.scene.BIMProperties.clash_sets.add()
|
||||
new.name = 'New Clash Set'
|
||||
new.tolerance = 0.01
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class RemoveClashSet(bpy.types.Operator):
|
||||
bl_idname = 'bim.remove_clash_set'
|
||||
bl_label = 'Remove Clash Set'
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
bpy.context.scene.BIMProperties.clash_sets.remove(self.index)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddClashSource(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_clash_source'
|
||||
bl_label = 'Add Clash Source'
|
||||
group: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
clash_set = bpy.context.scene.BIMProperties.clash_sets[bpy.context.scene.BIMProperties.active_clash_set_index]
|
||||
source = getattr(clash_set, self.group).add()
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class RemoveClashSource(bpy.types.Operator):
|
||||
bl_idname = 'bim.remove_clash_source'
|
||||
bl_label = 'Remove Clash Source'
|
||||
index: bpy.props.IntProperty()
|
||||
group: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
clash_set = bpy.context.scene.BIMProperties.clash_sets[bpy.context.scene.BIMProperties.active_clash_set_index]
|
||||
getattr(clash_set, self.group).remove(self.index)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class SelectClashSource(bpy.types.Operator):
|
||||
bl_idname = "bim.select_clash_source"
|
||||
bl_label = "Select Clash Source"
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
index: bpy.props.IntProperty()
|
||||
group: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
clash_set = bpy.context.scene.BIMProperties.clash_sets[bpy.context.scene.BIMProperties.active_clash_set_index]
|
||||
getattr(clash_set, self.group)[self.index].name = self.filepath
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
class ExecuteIfcClash(bpy.types.Operator):
|
||||
bl_idname = 'bim.execute_ifc_clash'
|
||||
bl_label = 'Execute IFC Clash'
|
||||
@@ -1172,8 +1233,24 @@ class ExecuteIfcClash(bpy.types.Operator):
|
||||
settings.output = self.filepath
|
||||
settings.logger = logging.getLogger('Clash')
|
||||
settings.logger.setLevel(logging.DEBUG)
|
||||
ifc_clasher = ifcclash.IfcClasher(
|
||||
bpy.context.scene.BIMProperties.ifc_clash_a, bpy.context.scene.BIMProperties.ifc_clash_b, settings)
|
||||
ifc_clasher = ifcclash.IfcClasher(settings)
|
||||
ifc_clasher.clash_sets = []
|
||||
for clash_set in bpy.context.scene.BIMProperties.clash_sets:
|
||||
self.a = []
|
||||
self.b = []
|
||||
for ab in ['a', 'b']:
|
||||
for data in getattr(clash_set, ab):
|
||||
clash_source = { 'file': data.name }
|
||||
if data.selector:
|
||||
clash_source['selector'] = data.selector
|
||||
clash_source['mode'] = data.mode
|
||||
getattr(self, ab).append(clash_source)
|
||||
ifc_clasher.clash_sets.append({
|
||||
'name': clash_set.name,
|
||||
'tolerance': clash_set.tolerance,
|
||||
'a': self.a,
|
||||
'b': self.b
|
||||
})
|
||||
ifc_clasher.clash()
|
||||
ifc_clasher.export()
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -467,6 +467,22 @@ class DocumentReference(PropertyGroup):
|
||||
referenced_document: StringProperty(name="Referenced Document")
|
||||
|
||||
|
||||
class ClashSource(PropertyGroup):
|
||||
name: StringProperty(name='File')
|
||||
selector: StringProperty(name='Selector')
|
||||
mode: EnumProperty(items=[
|
||||
('i', 'Include', 'Only the selected objects are included for clashing'),
|
||||
('e', 'Exclude', 'All objects except the selected objects are included for clashing')
|
||||
], name='Mode')
|
||||
|
||||
|
||||
class ClashSet(PropertyGroup):
|
||||
name: StringProperty(name='Name')
|
||||
tolerance: FloatProperty(name='Tolerance')
|
||||
a: CollectionProperty(name='Group A', type=ClashSource)
|
||||
b: CollectionProperty(name='Group B', type=ClashSource)
|
||||
|
||||
|
||||
class BcfTopic(PropertyGroup):
|
||||
name: StringProperty(name='Name')
|
||||
|
||||
@@ -929,8 +945,8 @@ class BIMProperties(PropertyGroup):
|
||||
active_document_information_index: IntProperty(name='Active Document Information Index')
|
||||
document_references: CollectionProperty(name='Document References', type=DocumentReference)
|
||||
active_document_reference_index: IntProperty(name='Active Document Reference Index')
|
||||
ifc_clash_a: StringProperty(name="IFC Clash A")
|
||||
ifc_clash_b: StringProperty(name="IFC Clash B")
|
||||
clash_sets: CollectionProperty(name='Clash Sets', type=ClashSet)
|
||||
active_clash_set_index: IntProperty(name='Active Clash Set Index')
|
||||
|
||||
|
||||
class BCFProperties(PropertyGroup):
|
||||
|
||||
@@ -1225,6 +1225,15 @@ class BIM_UL_topics(bpy.types.UIList):
|
||||
layout.label(text="", translate=False)
|
||||
|
||||
|
||||
class BIM_UL_clash_sets(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
ob = data
|
||||
if item:
|
||||
layout.prop(item, 'name', text='', emboss=False)
|
||||
else:
|
||||
layout.label(text="", translate=False)
|
||||
|
||||
|
||||
class BIM_UL_document_information(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
ob = data
|
||||
@@ -1284,16 +1293,64 @@ class BIM_PT_ifcclash(Panel):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
|
||||
scene = context.scene
|
||||
props = scene.BIMProperties
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, 'ifc_clash_a')
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, 'ifc_clash_b')
|
||||
|
||||
row = layout.row()
|
||||
row.operator('bim.execute_ifc_clash')
|
||||
row.operator('bim.add_clash_set')
|
||||
|
||||
if not props.clash_sets:
|
||||
return
|
||||
|
||||
layout.template_list('BIM_UL_clash_sets', '', props, 'clash_sets', props, 'active_clash_set_index')
|
||||
|
||||
if props.active_clash_set_index < len(props.clash_sets):
|
||||
clash_set = props.clash_sets[props.active_clash_set_index]
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(clash_set, 'name')
|
||||
row.operator('bim.remove_clash_set', icon='X', text='').index = props.active_clash_set_index
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(clash_set, 'tolerance')
|
||||
|
||||
layout.label(text="Group A:")
|
||||
row = layout.row()
|
||||
row.operator('bim.add_clash_source').group = 'a'
|
||||
|
||||
for index, source in enumerate(clash_set.a):
|
||||
row = layout.row(align=True)
|
||||
row.prop(source, 'name', text='')
|
||||
op = row.operator('bim.select_clash_source', icon='FILE_FOLDER', text='')
|
||||
op.index = index
|
||||
op.group = 'a'
|
||||
op = row.operator('bim.remove_clash_source', icon='X', text='')
|
||||
op.index = index
|
||||
op.group = 'a'
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(source, 'mode', text='')
|
||||
row.prop(source, 'selector', text='')
|
||||
|
||||
layout.label(text="Group B:")
|
||||
row = layout.row()
|
||||
row.operator('bim.add_clash_source').group = 'b'
|
||||
|
||||
for index, source in enumerate(clash_set.b):
|
||||
row = layout.row(align=True)
|
||||
row.prop(source, 'name', text='')
|
||||
op = row.operator('bim.select_clash_source', icon='FILE_FOLDER', text='')
|
||||
op.index = index
|
||||
op.group = 'b'
|
||||
op = row.operator('bim.remove_clash_source', icon='X', text='')
|
||||
op.index = index
|
||||
op.group = 'b'
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(source, 'mode', text='')
|
||||
row.prop(source, 'selector', text='')
|
||||
|
||||
row = layout.row()
|
||||
row.operator('bim.execute_ifc_clash')
|
||||
|
||||
|
||||
@@ -83,14 +83,11 @@ class IfcClasher:
|
||||
for result in results:
|
||||
del result['a_cm']
|
||||
del result['b_cm']
|
||||
for data in result['a']:
|
||||
del data['ifc']
|
||||
del data['meshes']
|
||||
for data in result['b']:
|
||||
del data['ifc']
|
||||
del data['meshes']
|
||||
print(results)
|
||||
|
||||
for ab in ['a', 'b']:
|
||||
for data in result[ab]:
|
||||
for key in ['ifc', 'meshes']:
|
||||
if key in data:
|
||||
del data[key]
|
||||
with open(self.settings.output, 'w', encoding='utf-8') as clashes_file:
|
||||
json.dump(results, clashes_file, indent=4)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user