New UI to assign multiple swept solids per object

This commit is contained in:
Dion Moult
2019-11-13 18:48:12 +11:00
parent 556a476f9f
commit cfe030378a
4 changed files with 163 additions and 67 deletions
@@ -31,9 +31,14 @@ classes = (
operator.SelectAudited, operator.SelectAudited,
operator.RejectElement, operator.RejectElement,
operator.SelectExternalMaterialDir, operator.SelectExternalMaterialDir,
operator.AddSweptSolid,
operator.RemoveSweptSolid,
operator.AssignSweptSolidOuterCurve, operator.AssignSweptSolidOuterCurve,
operator.SelectSweptSolidOuterCurve,
operator.AddSweptSolidInnerCurve, operator.AddSweptSolidInnerCurve,
operator.SelectSweptSolidInnerCurves,
operator.AssignSweptSolidExtrusion, operator.AssignSweptSolidExtrusion,
operator.SelectSweptSolidExtrusion,
operator.AssignPset, operator.AssignPset,
operator.UnassignPset, operator.UnassignPset,
operator.AddPset, operator.AddPset,
@@ -61,6 +66,7 @@ classes = (
ui.GlobalId, ui.GlobalId,
ui.BIMObjectProperties, ui.BIMObjectProperties,
ui.BIMMaterialProperties, ui.BIMMaterialProperties,
ui.SweptSolid,
ui.BIMMeshProperties, ui.BIMMeshProperties,
ui.GISPanel, ui.GISPanel,
ui.BIMPanel, ui.BIMPanel,
@@ -1397,50 +1397,40 @@ class IfcExporter():
def create_swept_solid_representation(self, representation): def create_swept_solid_representation(self, representation):
object = representation['raw_object'] object = representation['raw_object']
mesh = representation['raw'] mesh = representation['raw']
outer_curve_index = None items = []
inner_curve_indices = [] for swept_solid in mesh.BIMMeshProperties.swept_solids:
extrusion_index = None extrusion_edge = self.get_edges_in_v_indices(object, json.loads(swept_solid.extrusion))[0]
for index, vg in enumerate(object.vertex_groups): inner_curves = []
if vg.name == 'outer-curve': if swept_solid.inner_curves:
outer_curve_index = index for indices in json.loads(swept_solid.inner_curves):
elif 'inner-curve' in vg.name: loop = self.get_loop_from_v_indices(object, indices)
inner_curve_indices.append(index) curve_ucs = self.get_curve_profile_coordinate_system(object, loop)
elif vg.name == 'extrusion': inner_curves.append(
extrusion_index = index self.create_polyline_from_loop(object, loop, curve_ucs))
extrusion_edge = self.get_edges_in_vg_index(object, extrusion_index)[0] outer_curve_loop = self.get_loop_from_v_indices(object, json.loads(swept_solid.outer_curve))
curve_ucs = self.get_curve_profile_coordinate_system(object, outer_curve_loop)
outer_curve = self.create_polyline_from_loop(object, outer_curve_loop, curve_ucs)
inner_curves = [] if inner_curves:
for index in inner_curve_indices: curve = self.file.createIfcArbitraryProfileDefWithVoids('AREA', None,
loop = self.get_loop_from_vg_index(object, index) outer_curve, inner_curves)
curve_ucs = self.get_curve_profile_coordinate_system(object, loop) else:
inner_curves.append( curve = self.file.createIfcArbitraryClosedProfileDef('AREA', None, outer_curve)
self.create_polyline_from_loop(object, loop, curve_ucs))
outer_curve_loop = self.get_loop_from_vg_index(object, outer_curve_index) direction = self.get_extrusion_direction(object, outer_curve_loop, extrusion_edge, curve_ucs)
curve_ucs = self.get_curve_profile_coordinate_system(object, outer_curve_loop) unit_direction = direction.normalized()
outer_curve = self.create_polyline_from_loop(object, outer_curve_loop, curve_ucs) position = self.create_ifc_axis_2_placement_3d(
curve_ucs['center'], curve_ucs['z_axis'], curve_ucs['x_axis'])
if inner_curves: items.append(self.file.createIfcExtrudedAreaSolid(
curve = self.file.createIfcArbitraryProfileDefWithVoids('AREA', None, curve, position, self.file.createIfcDirection((
outer_curve, inner_curves) unit_direction.x, unit_direction.y, unit_direction.z)),
else: self.convert_si_to_unit(direction.length)))
curve = self.file.createIfcArbitraryClosedProfileDef('AREA', None, outer_curve)
direction = self.get_extrusion_direction(object, outer_curve_loop, extrusion_edge, curve_ucs)
unit_direction = direction.normalized()
position = self.create_ifc_axis_2_placement_3d(
curve_ucs['center'], curve_ucs['z_axis'], curve_ucs['x_axis'])
extruded_area_solid = self.file.createIfcExtrudedAreaSolid(
curve, position, self.file.createIfcDirection((
unit_direction.x, unit_direction.y, unit_direction.z)),
self.convert_si_to_unit(direction.length))
return self.file.createIfcShapeRepresentation( return self.file.createIfcShapeRepresentation(
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'], self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
representation['subcontext'], 'SweptSolid', representation['subcontext'], 'SweptSolid', items)
[extruded_area_solid])
def get_start_and_end_of_extrusion(self, profile_points, extrusion_edge): def get_start_and_end_of_extrusion(self, profile_points, extrusion_edge):
if extrusion_edge.vertices[0] in profile_points: if extrusion_edge.vertices[0] in profile_points:
@@ -1483,17 +1473,15 @@ class IfcExporter():
start, end = self.get_start_and_end_of_extrusion(outer_curve_loop, extrusion_edge) start, end = self.get_start_and_end_of_extrusion(outer_curve_loop, extrusion_edge)
return curve_ucs['matrix'] @ (curve_ucs['center'] + (object.data.vertices[end].co - object.data.vertices[start].co)) return curve_ucs['matrix'] @ (curve_ucs['center'] + (object.data.vertices[end].co - object.data.vertices[start].co))
def get_loop_from_vg_index(self, object, vg_index): def get_loop_from_v_indices(self, object, indices):
edges = self.get_edges_in_vg_index(object, vg_index) edges = self.get_edges_in_v_indices(object, indices)
loop = self.get_loop_from_edges(edges) loop = self.get_loop_from_edges(edges)
loop.pop(-1) loop.pop(-1)
return loop return loop
def get_edges_in_vg_index(self, object, index): def get_edges_in_v_indices(self, object, indices):
return [ e for e in object.data.edges if ( return [ e for e in object.data.edges if (
index in [ g.group for g in object.data.vertices[e.vertices[0]].groups ] and e.vertices[0] in indices and e.vertices[1] in indices) ]
index in [ g.group for g in object.data.vertices[e.vertices[1]].groups ]
) ]
def get_loop_from_edges(self, edges): def get_loop_from_edges(self, edges):
while edges: while edges:
+97 -16
View File
@@ -1,5 +1,6 @@
import bpy import bpy
import time import time
import json
import logging import logging
from . import ifcopenshell from . import ifcopenshell
from . import export_ifc from . import export_ifc
@@ -343,47 +344,127 @@ class RemoveAttribute(bpy.types.Operator):
bpy.context.active_object.BIMObjectProperties.attributes.remove(self.attribute_index) bpy.context.active_object.BIMObjectProperties.attributes.remove(self.attribute_index)
return {'FINISHED'} return {'FINISHED'}
class AddSweptSolid(bpy.types.Operator):
bl_idname = 'bim.add_swept_solid'
bl_label = 'Add Swept Solid'
def execute(self, context):
swept_solids = bpy.context.active_object.data.BIMMeshProperties.swept_solids
swept_solid = swept_solids.add()
swept_solid.name = 'Swept Solid {}'.format(len(swept_solids))
return {'FINISHED'}
class RemoveSweptSolid(bpy.types.Operator):
bl_idname = 'bim.remove_swept_solid'
bl_label = 'Remove Swept Solid'
index: bpy.props.IntProperty()
def execute(self, context):
bpy.context.active_object.data.BIMMeshProperties.swept_solids.remove(self.index)
return {'FINISHED'}
class AssignSweptSolidOuterCurve(bpy.types.Operator): class AssignSweptSolidOuterCurve(bpy.types.Operator):
bl_idname = 'bim.assign_swept_solid_outer_curve' bl_idname = 'bim.assign_swept_solid_outer_curve'
bl_label = 'Assign Outer Curve' bl_label = 'Assign Outer Curve'
index: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
if bpy.context.mode != 'EDIT_MESH': if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'} return {'FINISHED'}
for vg in bpy.context.active_object.vertex_groups: bpy.ops.object.mode_set(mode='OBJECT')
if vg.name == 'outer-curve': bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.vertex_group_set_active(group=vg.name) vertices = [v.index for v in bpy.context.active_object.data.vertices if v.select == True]
bpy.ops.object.vertex_group_remove() print(vertices)
break bpy.context.active_object.data.BIMMeshProperties.swept_solids[self.index].outer_curve = json.dumps(vertices)
bpy.ops.object.vertex_group_assign_new() return {'FINISHED'}
bpy.context.active_object.vertex_groups[bpy.context.active_object.vertex_groups[-1].name].name = 'outer-curve'
class SelectSweptSolidOuterCurve(bpy.types.Operator):
bl_idname = 'bim.select_swept_solid_outer_curve'
bl_label = 'Select Outer Curve'
index: bpy.props.IntProperty()
def execute(self, context):
if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'}
bpy.ops.object.mode_set(mode='OBJECT')
outer_curve = bpy.context.active_object.data.BIMMeshProperties.swept_solids[self.index].outer_curve
if not outer_curve:
return {'FINISHED'}
indices = json.loads(outer_curve)
for index in indices:
bpy.context.active_object.data.vertices[index].select = True
bpy.ops.object.mode_set(mode='EDIT')
return {'FINISHED'} return {'FINISHED'}
class AddSweptSolidInnerCurve(bpy.types.Operator): class AddSweptSolidInnerCurve(bpy.types.Operator):
bl_idname = 'bim.add_swept_solid_inner_curve' bl_idname = 'bim.add_swept_solid_inner_curve'
bl_label = 'Add Inner Curve' bl_label = 'Add Inner Curve'
index: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
if bpy.context.mode != 'EDIT_MESH': if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'} return {'FINISHED'}
bpy.ops.object.vertex_group_assign_new() bpy.ops.object.mode_set(mode='OBJECT')
bpy.context.active_object.vertex_groups[bpy.context.active_object.vertex_groups[-1].name].name = 'inner-curve' bpy.ops.object.mode_set(mode='EDIT')
vertices = [v.index for v in bpy.context.active_object.data.vertices if v.select == True]
swept_solid = bpy.context.active_object.data.BIMMeshProperties.swept_solids[self.index]
if swept_solid.inner_curves:
curves = json.loads(swept_solid.inner_curves)
else:
curves = []
curves.append(vertices)
swept_solid.inner_curves = json.dumps(curves)
return {'FINISHED'}
class SelectSweptSolidInnerCurves(bpy.types.Operator):
bl_idname = 'bim.select_swept_solid_inner_curves'
bl_label = 'Select Inner Curves'
index: bpy.props.IntProperty()
def execute(self, context):
if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'}
bpy.ops.object.mode_set(mode='OBJECT')
inner_curves = bpy.context.active_object.data.BIMMeshProperties.swept_solids[self.index].inner_curves
if not inner_curves:
return {'FINISHED'}
curves = json.loads(inner_curves)
for curve in curves:
for index in curve:
bpy.context.active_object.data.vertices[index].select = True
bpy.ops.object.mode_set(mode='EDIT')
return {'FINISHED'} return {'FINISHED'}
class AssignSweptSolidExtrusion(bpy.types.Operator): class AssignSweptSolidExtrusion(bpy.types.Operator):
bl_idname = 'bim.assign_swept_solid_extrusion' bl_idname = 'bim.assign_swept_solid_extrusion'
bl_label = 'Assign Extrusion' bl_label = 'Assign Extrusion'
index: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
if bpy.context.mode != 'EDIT_MESH': if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'} return {'FINISHED'}
for vg in bpy.context.active_object.vertex_groups: bpy.ops.object.mode_set(mode='OBJECT')
if vg.name == 'extrusion': bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.vertex_group_set_active(group=vg.name) vertices = [v.index for v in bpy.context.active_object.data.vertices if v.select == True]
bpy.ops.object.vertex_group_remove() bpy.context.active_object.data.BIMMeshProperties.swept_solids[self.index].extrusion = json.dumps(vertices)
break return {'FINISHED'}
bpy.ops.object.vertex_group_assign_new()
bpy.context.active_object.vertex_groups[bpy.context.active_object.vertex_groups[-1].name].name = 'extrusion' class SelectSweptSolidExtrusion(bpy.types.Operator):
bl_idname = 'bim.select_swept_solid_extrusion'
bl_label = 'Select Extrusion'
index: bpy.props.IntProperty()
def execute(self, context):
if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'}
bpy.ops.object.mode_set(mode='OBJECT')
extrusion = bpy.context.active_object.data.BIMMeshProperties.swept_solids[self.index].extrusion
if not extrusion:
return {'FINISHED'}
indices = json.loads(extrusion)
for index in indices:
bpy.context.active_object.data.vertices[index].select = True
bpy.ops.object.mode_set(mode='EDIT')
return {'FINISHED'} return {'FINISHED'}
class SelectExternalMaterialDir(bpy.types.Operator): class SelectExternalMaterialDir(bpy.types.Operator):
+29 -8
View File
@@ -147,9 +147,16 @@ class BIMMaterialProperties(bpy.types.PropertyGroup):
identification: bpy.props.StringProperty(name="Identification") identification: bpy.props.StringProperty(name="Identification")
name: bpy.props.StringProperty(name="Name") name: bpy.props.StringProperty(name="Name")
class SweptSolid(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(name="Name")
outer_curve: bpy.props.StringProperty(name="Outer Curve")
inner_curves: bpy.props.StringProperty(name="Inner Curves")
extrusion: bpy.props.StringProperty(name="Extrusion")
class BIMMeshProperties(bpy.types.PropertyGroup): class BIMMeshProperties(bpy.types.PropertyGroup):
is_wireframe: bpy.props.BoolProperty(name="Is Wireframe") is_wireframe: bpy.props.BoolProperty(name="Is Wireframe")
is_swept_solid: bpy.props.BoolProperty(name="Is Swept Solid") is_swept_solid: bpy.props.BoolProperty(name="Is Swept Solid")
swept_solids: bpy.props.CollectionProperty(name="Swept Solids", type=SweptSolid)
class ObjectPanel(bpy.types.Panel): class ObjectPanel(bpy.types.Panel):
bl_label = 'IFC Object' bl_label = 'IFC Object'
@@ -175,7 +182,7 @@ class ObjectPanel(bpy.types.Panel):
row = layout.row(align=True) row = layout.row(align=True)
row.prop(attribute, 'name', text='') row.prop(attribute, 'name', text='')
row.prop(attribute, 'string_value', text='') row.prop(attribute, 'string_value', text='')
row.operator('bim.remove_attribute', icon='CANCEL', text='').attribute_index = index row.operator('bim.remove_attribute', icon='X', text='').attribute_index = index
row = layout.row() row = layout.row()
row.prop(bpy.context.active_object.BIMObjectProperties, 'attributes') row.prop(bpy.context.active_object.BIMObjectProperties, 'attributes')
@@ -188,7 +195,7 @@ class ObjectPanel(bpy.types.Panel):
row = layout.row(align=True) row = layout.row(align=True)
row.prop(pset, 'name', text='') row.prop(pset, 'name', text='')
row.prop(pset, 'file', text='') row.prop(pset, 'file', text='')
row.operator('bim.remove_pset', icon='CANCEL', text='').pset_index = index row.operator('bim.remove_pset', icon='X', text='').pset_index = index
row = layout.row() row = layout.row()
row.prop(bpy.context.active_object.BIMObjectProperties, 'psets') row.prop(bpy.context.active_object.BIMObjectProperties, 'psets')
@@ -201,7 +208,7 @@ class ObjectPanel(bpy.types.Panel):
for index, document in enumerate(bpy.context.active_object.BIMObjectProperties.documents): for index, document in enumerate(bpy.context.active_object.BIMObjectProperties.documents):
row = layout.row(align=True) row = layout.row(align=True)
row.prop(document, 'file', text='') row.prop(document, 'file', text='')
row.operator('bim.remove_document', icon='CANCEL', text='').document_index = index row.operator('bim.remove_document', icon='X', text='').document_index = index
row = layout.row() row = layout.row()
row.prop(bpy.context.active_object.BIMObjectProperties, 'documents') row.prop(bpy.context.active_object.BIMObjectProperties, 'documents')
@@ -212,7 +219,7 @@ class ObjectPanel(bpy.types.Panel):
row = layout.row(align=True) row = layout.row(align=True)
row.prop(classification, 'identification', text='') row.prop(classification, 'identification', text='')
row.prop(classification, 'name', text='') row.prop(classification, 'name', text='')
row.operator('bim.remove_classification', icon='CANCEL', text='').classification_index = index row.operator('bim.remove_classification', icon='X', text='').classification_index = index
row = layout.row() row = layout.row()
row.prop(bpy.context.active_object.BIMObjectProperties, 'classifications') row.prop(bpy.context.active_object.BIMObjectProperties, 'classifications')
@@ -233,11 +240,25 @@ class MeshPanel(bpy.types.Panel):
row.prop(bpy.context.active_object.data.BIMMeshProperties, 'is_wireframe') row.prop(bpy.context.active_object.data.BIMMeshProperties, 'is_wireframe')
row = layout.row() row = layout.row()
row.prop(bpy.context.active_object.data.BIMMeshProperties, 'is_swept_solid') row.prop(bpy.context.active_object.data.BIMMeshProperties, 'is_swept_solid')
row = layout.row(align=True)
row.operator('bim.assign_swept_solid_outer_curve')
row.operator('bim.add_swept_solid_inner_curve')
row = layout.row() row = layout.row()
row.operator('bim.assign_swept_solid_extrusion') row.operator('bim.add_swept_solid')
for index, swept_solid in enumerate(bpy.context.active_object.data.BIMMeshProperties.swept_solids):
row = layout.row(align=True)
row.prop(swept_solid, 'name', text='')
row.operator('bim.remove_swept_solid', icon='X', text='').index = index
row = layout.row()
sub = row.row(align=True)
sub.operator('bim.assign_swept_solid_outer_curve').index = index
sub.operator('bim.select_swept_solid_outer_curve', icon='RESTRICT_SELECT_OFF', text='').index = index
sub = row.row(align=True)
sub.operator('bim.add_swept_solid_inner_curve').index = index
sub.operator('bim.select_swept_solid_inner_curves', icon='RESTRICT_SELECT_OFF', text='').index = index
row = layout.row(align=True)
row.operator('bim.assign_swept_solid_extrusion').index = index
row.operator('bim.select_swept_solid_extrusion', icon='RESTRICT_SELECT_OFF', text='').index = index
row = layout.row()
row.prop(bpy.context.active_object.data.BIMMeshProperties, 'swept_solids')
class MaterialPanel(bpy.types.Panel): class MaterialPanel(bpy.types.Panel):
bl_label = 'IFC Materials' bl_label = 'IFC Materials'