mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 10:11:46 +00:00
Improve drawings management UI from a single dropdown to a proper list
This commit is contained in:
@@ -119,8 +119,6 @@ if bpy is not None:
|
|||||||
operator.OpenCompiledSheet,
|
operator.OpenCompiledSheet,
|
||||||
operator.AddViewToSheet,
|
operator.AddViewToSheet,
|
||||||
operator.CreateSheets,
|
operator.CreateSheets,
|
||||||
operator.GenerateDigitalTwin,
|
|
||||||
operator.CreateView,
|
|
||||||
operator.OpenView,
|
operator.OpenView,
|
||||||
operator.ActivateView,
|
operator.ActivateView,
|
||||||
operator.ExecuteIfcDiff,
|
operator.ExecuteIfcDiff,
|
||||||
@@ -178,6 +176,8 @@ if bpy is not None:
|
|||||||
operator.CalculateObjectVolumes,
|
operator.CalculateObjectVolumes,
|
||||||
operator.AddOpening,
|
operator.AddOpening,
|
||||||
operator.SetOverrideColour,
|
operator.SetOverrideColour,
|
||||||
|
operator.AddDrawing,
|
||||||
|
operator.RemoveDrawing,
|
||||||
operator.AddDrawingStyle,
|
operator.AddDrawingStyle,
|
||||||
operator.RemoveDrawingStyle,
|
operator.RemoveDrawingStyle,
|
||||||
operator.SaveDrawingStyle,
|
operator.SaveDrawingStyle,
|
||||||
@@ -198,6 +198,7 @@ if bpy is not None:
|
|||||||
prop.ClashSource,
|
prop.ClashSource,
|
||||||
prop.ClashSet,
|
prop.ClashSet,
|
||||||
prop.Constraint,
|
prop.Constraint,
|
||||||
|
prop.Drawing,
|
||||||
prop.DrawingStyle,
|
prop.DrawingStyle,
|
||||||
prop.BcfTopic,
|
prop.BcfTopic,
|
||||||
prop.BcfTopicLabel,
|
prop.BcfTopicLabel,
|
||||||
@@ -224,7 +225,8 @@ if bpy is not None:
|
|||||||
prop.BIMCameraProperties,
|
prop.BIMCameraProperties,
|
||||||
prop.BIMTextProperties,
|
prop.BIMTextProperties,
|
||||||
ui.BIM_PT_section_plane,
|
ui.BIM_PT_section_plane,
|
||||||
ui.BIM_PT_documentation,
|
ui.BIM_PT_drawings,
|
||||||
|
ui.BIM_PT_sheets,
|
||||||
ui.BIM_PT_bim,
|
ui.BIM_PT_bim,
|
||||||
ui.BIM_PT_psets,
|
ui.BIM_PT_psets,
|
||||||
ui.BIM_PT_classifications,
|
ui.BIM_PT_classifications,
|
||||||
|
|||||||
@@ -2021,27 +2021,6 @@ class RemoveSubcontext(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class CreateView(bpy.types.Operator):
|
|
||||||
bl_idname = 'bim.create_view'
|
|
||||||
bl_label = 'Create View'
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
if not bpy.data.collections.get('Views'):
|
|
||||||
bpy.context.scene.collection.children.link(bpy.data.collections.new('Views'))
|
|
||||||
views_collection = bpy.data.collections.get('Views')
|
|
||||||
view_collection = bpy.data.collections.new('IfcGroup/' + bpy.context.scene.DocProperties.view_name)
|
|
||||||
views_collection.children.link(view_collection)
|
|
||||||
camera = bpy.data.objects.new('IfcGroup/' + bpy.context.scene.DocProperties.view_name,
|
|
||||||
bpy.data.cameras.new(bpy.context.scene.DocProperties.view_name))
|
|
||||||
camera.data.type = 'ORTHO'
|
|
||||||
camera.data.BIMCameraProperties.diagram_scale = '1:100'
|
|
||||||
bpy.context.scene.camera = camera
|
|
||||||
view_collection.objects.link(camera)
|
|
||||||
area = next(area for area in bpy.context.screen.areas if area.type == 'VIEW_3D')
|
|
||||||
area.spaces[0].region_3d.view_perspective = 'CAMERA'
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
|
|
||||||
class OpenView(bpy.types.Operator):
|
class OpenView(bpy.types.Operator):
|
||||||
bl_idname = 'bim.open_view'
|
bl_idname = 'bim.open_view'
|
||||||
bl_label = 'Open View'
|
bl_label = 'Open View'
|
||||||
@@ -2243,21 +2222,12 @@ class CreateSheets(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class GenerateDigitalTwin(bpy.types.Operator):
|
|
||||||
bl_idname = 'bim.generate_digital_twin'
|
|
||||||
bl_label = 'Generate Digital Twin'
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
# Does absolutely nothing at all :D
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
|
|
||||||
class ActivateView(bpy.types.Operator):
|
class ActivateView(bpy.types.Operator):
|
||||||
bl_idname = 'bim.activate_view'
|
bl_idname = 'bim.activate_view'
|
||||||
bl_label = 'Activate View'
|
bl_label = 'Activate View'
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
camera = bpy.data.objects.get('IfcGroup/' + bpy.context.scene.DocProperties.available_views)
|
camera = bpy.context.scene.DocProperties.drawings[bpy.context.scene.DocProperties.active_drawing_index].camera
|
||||||
if not camera:
|
if not camera:
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
bpy.context.scene.camera = camera
|
bpy.context.scene.camera = camera
|
||||||
@@ -3487,3 +3457,45 @@ class ActivateDrawingStyle(bpy.types.Operator):
|
|||||||
bpy.context.scene.display.shading.single_color = style['bpy.context.scene.display.shading.single_color']
|
bpy.context.scene.display.shading.single_color = style['bpy.context.scene.display.shading.single_color']
|
||||||
bpy.context.scene.view_settings.use_curve_mapping = style['bpy.context.scene.view_settings.use_curve_mapping']
|
bpy.context.scene.view_settings.use_curve_mapping = style['bpy.context.scene.view_settings.use_curve_mapping']
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class AddDrawing(bpy.types.Operator):
|
||||||
|
bl_idname = 'bim.add_drawing'
|
||||||
|
bl_label = 'Add Drawing'
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
new = bpy.context.scene.DocProperties.drawings.add()
|
||||||
|
new.name = 'DRAWING {}'.format(len(bpy.context.scene.DocProperties.drawings))
|
||||||
|
if not bpy.data.collections.get('Views'):
|
||||||
|
bpy.context.scene.collection.children.link(bpy.data.collections.new('Views'))
|
||||||
|
views_collection = bpy.data.collections.get('Views')
|
||||||
|
view_collection = bpy.data.collections.new('IfcGroup/' + new.name)
|
||||||
|
views_collection.children.link(view_collection)
|
||||||
|
camera = bpy.data.objects.new('IfcGroup/' + new.name,
|
||||||
|
bpy.data.cameras.new('IfcGroup/' + new.name))
|
||||||
|
camera.location = (0, 0, 1.7) # The view shall be 1.7m above the origin
|
||||||
|
camera.data.type = 'ORTHO'
|
||||||
|
camera.data.ortho_scale = 50 # The default of 6m is too small
|
||||||
|
camera.data.BIMCameraProperties.diagram_scale = '1:100'
|
||||||
|
bpy.context.scene.camera = camera
|
||||||
|
view_collection.objects.link(camera)
|
||||||
|
area = next(area for area in bpy.context.screen.areas if area.type == 'VIEW_3D')
|
||||||
|
area.spaces[0].region_3d.view_perspective = 'CAMERA'
|
||||||
|
new.camera = camera
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveDrawing(bpy.types.Operator):
|
||||||
|
bl_idname = 'bim.remove_drawing'
|
||||||
|
bl_label = 'Remove Drawing'
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
camera = props.drawings[self.index].camera
|
||||||
|
collection = camera.users_collection[0]
|
||||||
|
for obj in collection.objects:
|
||||||
|
bpy.data.objects.remove(obj)
|
||||||
|
bpy.data.collections.remove(collection, do_unlink=True)
|
||||||
|
props.drawings.remove(self.index)
|
||||||
|
return {'FINISHED'}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ subcontexts_enum = []
|
|||||||
target_views_enum = []
|
target_views_enum = []
|
||||||
persons_enum = []
|
persons_enum = []
|
||||||
organisations_enum = []
|
organisations_enum = []
|
||||||
views_enum = []
|
|
||||||
sheets_enum = []
|
sheets_enum = []
|
||||||
bcfviewpoints_enum = []
|
bcfviewpoints_enum = []
|
||||||
|
|
||||||
@@ -149,6 +148,14 @@ def getDiagramScales(self, context):
|
|||||||
return diagram_scales_enum
|
return diagram_scales_enum
|
||||||
|
|
||||||
|
|
||||||
|
def updateDrawingName(self, context):
|
||||||
|
if self.camera.name == self.name:
|
||||||
|
return
|
||||||
|
self.camera.name = 'IfcGroup/{}'.format(self.name)
|
||||||
|
self.camera.users_collection[0].name = self.camera.name
|
||||||
|
self.name = self.camera.name.split('/')[1]
|
||||||
|
|
||||||
|
|
||||||
def getBoundaryConditionClasses(self, context):
|
def getBoundaryConditionClasses(self, context):
|
||||||
return [(c, c, '') for c in
|
return [(c, c, '') for c in
|
||||||
['IfcBoundaryEdgeCondition', 'IfcBoundaryFaceCondition',
|
['IfcBoundaryEdgeCondition', 'IfcBoundaryFaceCondition',
|
||||||
@@ -393,19 +400,6 @@ def getTargetViews(self, context):
|
|||||||
return target_views_enum
|
return target_views_enum
|
||||||
|
|
||||||
|
|
||||||
def getViews(self, context):
|
|
||||||
global views_enum
|
|
||||||
views_enum.clear()
|
|
||||||
views_collection = bpy.data.collections.get('Views')
|
|
||||||
if not views_collection:
|
|
||||||
return views_enum
|
|
||||||
for collection in views_collection.children:
|
|
||||||
for obj in collection.objects:
|
|
||||||
if obj.type == 'CAMERA':
|
|
||||||
views_enum.append((obj.name.split('/')[1], obj.name.split('/')[1], ''))
|
|
||||||
return views_enum
|
|
||||||
|
|
||||||
|
|
||||||
def refreshSheets(self, context):
|
def refreshSheets(self, context):
|
||||||
global sheets_enum
|
global sheets_enum
|
||||||
sheets_enum.clear()
|
sheets_enum.clear()
|
||||||
@@ -441,6 +435,11 @@ class Subcontext(PropertyGroup):
|
|||||||
target_view: StringProperty(name='Target View')
|
target_view: StringProperty(name='Target View')
|
||||||
|
|
||||||
|
|
||||||
|
class Drawing(PropertyGroup):
|
||||||
|
name: StringProperty(name='Name', update=updateDrawingName)
|
||||||
|
camera: PointerProperty(name='Camera', type=bpy.types.Object)
|
||||||
|
|
||||||
|
|
||||||
class DrawingStyle(PropertyGroup):
|
class DrawingStyle(PropertyGroup):
|
||||||
name: StringProperty(name='Name')
|
name: StringProperty(name='Name')
|
||||||
raster_style: StringProperty(name='Raster Style')
|
raster_style: StringProperty(name='Raster Style')
|
||||||
@@ -454,8 +453,8 @@ class DocProperties(PropertyGroup):
|
|||||||
should_recut_selected: BoolProperty(name="Should Recut Selected Only", default=False)
|
should_recut_selected: BoolProperty(name="Should Recut Selected Only", default=False)
|
||||||
should_render: BoolProperty(name="Should Render", default=True)
|
should_render: BoolProperty(name="Should Render", default=True)
|
||||||
should_extract: BoolProperty(name="Should Extract", default=True)
|
should_extract: BoolProperty(name="Should Extract", default=True)
|
||||||
view_name: StringProperty(name="View Name")
|
drawings: CollectionProperty(name='Drawings', type=Drawing)
|
||||||
available_views: EnumProperty(items=getViews, name="Available Views")
|
active_drawing_index: IntProperty(name='Active Drawing Index')
|
||||||
sheet_name: StringProperty(name="Sheet Name", update=refreshSheets)
|
sheet_name: StringProperty(name="Sheet Name", update=refreshSheets)
|
||||||
available_sheets: EnumProperty(items=getSheets, name="Available Sheets")
|
available_sheets: EnumProperty(items=getSheets, name="Available Sheets")
|
||||||
ifc_files: CollectionProperty(name='IFCs', type=StrProperty)
|
ifc_files: CollectionProperty(name='IFCs', type=StrProperty)
|
||||||
|
|||||||
@@ -716,9 +716,44 @@ class BIM_PT_gis(Panel):
|
|||||||
row.operator('bim.convert_local_to_global')
|
row.operator('bim.convert_local_to_global')
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_documentation(Panel):
|
class BIM_PT_drawings(Panel):
|
||||||
bl_label = "Drawings and Sheets"
|
bl_label = "Drawings"
|
||||||
bl_idname = "BIM_PT_documentation"
|
bl_idname = "BIM_PT_drawings"
|
||||||
|
bl_space_type = 'PROPERTIES'
|
||||||
|
bl_region_type = 'WINDOW'
|
||||||
|
bl_context = 'output'
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
|
||||||
|
if props.drawings:
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator('bim.add_drawing')
|
||||||
|
op = row.operator('bim.open_view', icon='URL', text='')
|
||||||
|
op.view = props.drawings[props.active_drawing_index].name
|
||||||
|
row.operator('bim.activate_view', icon='SCENE', text='')
|
||||||
|
row.operator('bim.remove_drawing', icon='X', text='').index = props.active_drawing_index
|
||||||
|
|
||||||
|
layout.template_list('BIM_UL_generic', '', props, 'drawings', props, 'active_drawing_index')
|
||||||
|
else:
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator('bim.add_drawing')
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.operator('bim.add_ifc_file')
|
||||||
|
|
||||||
|
for index, ifc_file in enumerate(props.ifc_files):
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.prop(ifc_file, 'name', text='IFC #{}'.format(index + 1))
|
||||||
|
row.operator('bim.select_doc_ifc_file', icon='FILE_FOLDER', text='')
|
||||||
|
row.operator('bim.remove_ifc_file', icon='X', text='').index = index
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_sheets(Panel):
|
||||||
|
bl_label = "Sheets"
|
||||||
|
bl_idname = "BIM_PT_sheets"
|
||||||
bl_space_type = 'PROPERTIES'
|
bl_space_type = 'PROPERTIES'
|
||||||
bl_region_type = 'WINDOW'
|
bl_region_type = 'WINDOW'
|
||||||
bl_context = 'output'
|
bl_context = 'output'
|
||||||
@@ -728,20 +763,10 @@ class BIM_PT_documentation(Panel):
|
|||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
props = bpy.context.scene.DocProperties
|
props = bpy.context.scene.DocProperties
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, 'view_name', text='Drawing Name')
|
|
||||||
row.operator('bim.create_view', icon='ADD', text='')
|
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(props, 'sheet_name')
|
row.prop(props, 'sheet_name')
|
||||||
row.operator('bim.create_sheet', icon='ADD', text='')
|
row.operator('bim.create_sheet', icon='ADD', text='')
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, 'available_views', text='Available Drawings')
|
|
||||||
op = row.operator('bim.open_view', icon='URL', text='')
|
|
||||||
op.view = bpy.context.scene.DocProperties.available_views
|
|
||||||
row.operator('bim.activate_view', icon='SCENE', text='')
|
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(props, 'available_sheets')
|
row.prop(props, 'available_sheets')
|
||||||
row.operator('bim.open_sheet', icon='URL', text='')
|
row.operator('bim.open_sheet', icon='URL', text='')
|
||||||
@@ -751,14 +776,53 @@ class BIM_PT_documentation(Panel):
|
|||||||
row.operator('bim.add_view_to_sheet')
|
row.operator('bim.add_view_to_sheet')
|
||||||
row.operator('bim.create_sheets')
|
row.operator('bim.create_sheets')
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.operator('bim.add_ifc_file')
|
|
||||||
|
|
||||||
for index, ifc_file in enumerate(props.ifc_files):
|
class BIM_PT_section_plane(Panel):
|
||||||
row = layout.row(align=True)
|
bl_label = "Temporary Section Cutaways"
|
||||||
row.prop(ifc_file, 'name', text='IFC #{}'.format(index + 1))
|
bl_idname = "BIM_PT_section_plane"
|
||||||
row.operator('bim.select_doc_ifc_file', icon='FILE_FOLDER', text='')
|
bl_space_type = 'PROPERTIES'
|
||||||
row.operator('bim.remove_ifc_file', icon='X', text='').index = index
|
bl_region_type = 'WINDOW'
|
||||||
|
bl_context = 'output'
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
props = bpy.context.scene.BIMProperties
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, 'should_section_selected_objects')
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, 'section_plane_colour')
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator('bim.add_section_plane')
|
||||||
|
row.operator('bim.remove_section_plane')
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_camera(Panel):
|
||||||
|
bl_label = "Drawing Generation"
|
||||||
|
bl_idname = "BIM_PT_camera"
|
||||||
|
bl_space_type = 'PROPERTIES'
|
||||||
|
bl_region_type = 'WINDOW'
|
||||||
|
bl_context = 'data'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
engine = context.engine
|
||||||
|
return context.camera and \
|
||||||
|
hasattr(context.active_object.data, "BIMCameraProperties")
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
if '/' not in context.active_object.name:
|
||||||
|
layout.label(text="This is not a BIM camera.")
|
||||||
|
return
|
||||||
|
|
||||||
|
layout.use_property_split = True
|
||||||
|
dprops = bpy.context.scene.DocProperties
|
||||||
|
props = context.active_object.data.BIMCameraProperties
|
||||||
|
|
||||||
layout.label(text="Annotation:")
|
layout.label(text="Annotation:")
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
@@ -792,55 +856,7 @@ class BIM_PT_documentation(Panel):
|
|||||||
op.obj_name = 'Section Level'
|
op.obj_name = 'Section Level'
|
||||||
op.data_type = 'curve'
|
op.data_type = 'curve'
|
||||||
|
|
||||||
row = layout.row()
|
layout.label(text="Generation Options:")
|
||||||
row.operator('bim.generate_digital_twin')
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_section_plane(Panel):
|
|
||||||
bl_label = "Temporary Section Cutaways"
|
|
||||||
bl_idname = "BIM_PT_section_plane"
|
|
||||||
bl_space_type = 'PROPERTIES'
|
|
||||||
bl_region_type = 'WINDOW'
|
|
||||||
bl_context = 'output'
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
props = bpy.context.scene.BIMProperties
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, 'should_section_selected_objects')
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, 'section_plane_colour')
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator('bim.add_section_plane')
|
|
||||||
row.operator('bim.remove_section_plane')
|
|
||||||
|
|
||||||
class BIM_PT_camera(Panel):
|
|
||||||
bl_label = "Drawing Generation"
|
|
||||||
bl_idname = "BIM_PT_camera"
|
|
||||||
bl_space_type = 'PROPERTIES'
|
|
||||||
bl_region_type = 'WINDOW'
|
|
||||||
bl_context = 'data'
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
engine = context.engine
|
|
||||||
return context.camera and \
|
|
||||||
hasattr(context.active_object.data, "BIMCameraProperties")
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
|
|
||||||
if '/' not in context.active_object.name:
|
|
||||||
layout.label(text="This is not a BIM camera.")
|
|
||||||
return
|
|
||||||
|
|
||||||
layout.use_property_split = True
|
|
||||||
dprops = bpy.context.scene.DocProperties
|
|
||||||
props = context.active_object.data.BIMCameraProperties
|
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(dprops, 'should_recut')
|
row.prop(dprops, 'should_recut')
|
||||||
|
|||||||
Reference in New Issue
Block a user