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.RejectElement,
operator.SelectExternalMaterialDir,
operator.AddSweptSolid,
operator.RemoveSweptSolid,
operator.AssignSweptSolidOuterCurve,
operator.SelectSweptSolidOuterCurve,
operator.AddSweptSolidInnerCurve,
operator.SelectSweptSolidInnerCurves,
operator.AssignSweptSolidExtrusion,
operator.SelectSweptSolidExtrusion,
operator.AssignPset,
operator.UnassignPset,
operator.AddPset,
@@ -61,6 +66,7 @@ classes = (
ui.GlobalId,
ui.BIMObjectProperties,
ui.BIMMaterialProperties,
ui.SweptSolid,
ui.BIMMeshProperties,
ui.GISPanel,
ui.BIMPanel,
@@ -1397,50 +1397,40 @@ class IfcExporter():
def create_swept_solid_representation(self, representation):
object = representation['raw_object']
mesh = representation['raw']
outer_curve_index = None
inner_curve_indices = []
extrusion_index = None
items = []
for swept_solid in mesh.BIMMeshProperties.swept_solids:
extrusion_edge = self.get_edges_in_v_indices(object, json.loads(swept_solid.extrusion))[0]
for index, vg in enumerate(object.vertex_groups):
if vg.name == 'outer-curve':
outer_curve_index = index
elif 'inner-curve' in vg.name:
inner_curve_indices.append(index)
elif vg.name == 'extrusion':
extrusion_index = index
inner_curves = []
if swept_solid.inner_curves:
for indices in json.loads(swept_solid.inner_curves):
loop = self.get_loop_from_v_indices(object, indices)
curve_ucs = self.get_curve_profile_coordinate_system(object, loop)
inner_curves.append(
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 = []
for index in inner_curve_indices:
loop = self.get_loop_from_vg_index(object, index)
curve_ucs = self.get_curve_profile_coordinate_system(object, loop)
inner_curves.append(
self.create_polyline_from_loop(object, loop, curve_ucs))
if inner_curves:
curve = self.file.createIfcArbitraryProfileDefWithVoids('AREA', None,
outer_curve, inner_curves)
else:
curve = self.file.createIfcArbitraryClosedProfileDef('AREA', None, outer_curve)
outer_curve_loop = self.get_loop_from_vg_index(object, outer_curve_index)
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)
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'])
if inner_curves:
curve = self.file.createIfcArbitraryProfileDefWithVoids('AREA', None,
outer_curve, inner_curves)
else:
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))
items.append(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(
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
representation['subcontext'], 'SweptSolid',
[extruded_area_solid])
representation['subcontext'], 'SweptSolid', items)
def get_start_and_end_of_extrusion(self, profile_points, extrusion_edge):
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)
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):
edges = self.get_edges_in_vg_index(object, vg_index)
def get_loop_from_v_indices(self, object, indices):
edges = self.get_edges_in_v_indices(object, indices)
loop = self.get_loop_from_edges(edges)
loop.pop(-1)
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 (
index in [ g.group for g in object.data.vertices[e.vertices[0]].groups ] and
index in [ g.group for g in object.data.vertices[e.vertices[1]].groups ]
) ]
e.vertices[0] in indices and e.vertices[1] in indices) ]
def get_loop_from_edges(self, edges):
while edges:
+97 -16
View File
@@ -1,5 +1,6 @@
import bpy
import time
import json
import logging
from . import ifcopenshell
from . import export_ifc
@@ -343,47 +344,127 @@ class RemoveAttribute(bpy.types.Operator):
bpy.context.active_object.BIMObjectProperties.attributes.remove(self.attribute_index)
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):
bl_idname = 'bim.assign_swept_solid_outer_curve'
bl_label = 'Assign Outer Curve'
index: bpy.props.IntProperty()
def execute(self, context):
if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'}
for vg in bpy.context.active_object.vertex_groups:
if vg.name == 'outer-curve':
bpy.ops.object.vertex_group_set_active(group=vg.name)
bpy.ops.object.vertex_group_remove()
break
bpy.ops.object.vertex_group_assign_new()
bpy.context.active_object.vertex_groups[bpy.context.active_object.vertex_groups[-1].name].name = 'outer-curve'
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')
vertices = [v.index for v in bpy.context.active_object.data.vertices if v.select == True]
print(vertices)
bpy.context.active_object.data.BIMMeshProperties.swept_solids[self.index].outer_curve = json.dumps(vertices)
return {'FINISHED'}
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'}
class AddSweptSolidInnerCurve(bpy.types.Operator):
bl_idname = 'bim.add_swept_solid_inner_curve'
bl_label = 'Add Inner Curve'
index: bpy.props.IntProperty()
def execute(self, context):
if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'}
bpy.ops.object.vertex_group_assign_new()
bpy.context.active_object.vertex_groups[bpy.context.active_object.vertex_groups[-1].name].name = 'inner-curve'
bpy.ops.object.mode_set(mode='OBJECT')
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'}
class AssignSweptSolidExtrusion(bpy.types.Operator):
bl_idname = 'bim.assign_swept_solid_extrusion'
bl_label = 'Assign Extrusion'
index: bpy.props.IntProperty()
def execute(self, context):
if bpy.context.mode != 'EDIT_MESH':
return {'FINISHED'}
for vg in bpy.context.active_object.vertex_groups:
if vg.name == 'extrusion':
bpy.ops.object.vertex_group_set_active(group=vg.name)
bpy.ops.object.vertex_group_remove()
break
bpy.ops.object.vertex_group_assign_new()
bpy.context.active_object.vertex_groups[bpy.context.active_object.vertex_groups[-1].name].name = 'extrusion'
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')
vertices = [v.index for v in bpy.context.active_object.data.vertices if v.select == True]
bpy.context.active_object.data.BIMMeshProperties.swept_solids[self.index].extrusion = json.dumps(vertices)
return {'FINISHED'}
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'}
class SelectExternalMaterialDir(bpy.types.Operator):
+29 -8
View File
@@ -147,9 +147,16 @@ class BIMMaterialProperties(bpy.types.PropertyGroup):
identification: bpy.props.StringProperty(name="Identification")
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):
is_wireframe: bpy.props.BoolProperty(name="Is Wireframe")
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):
bl_label = 'IFC Object'
@@ -175,7 +182,7 @@ class ObjectPanel(bpy.types.Panel):
row = layout.row(align=True)
row.prop(attribute, 'name', 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.prop(bpy.context.active_object.BIMObjectProperties, 'attributes')
@@ -188,7 +195,7 @@ class ObjectPanel(bpy.types.Panel):
row = layout.row(align=True)
row.prop(pset, 'name', 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.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):
row = layout.row(align=True)
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.prop(bpy.context.active_object.BIMObjectProperties, 'documents')
@@ -212,7 +219,7 @@ class ObjectPanel(bpy.types.Panel):
row = layout.row(align=True)
row.prop(classification, 'identification', 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.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 = layout.row()
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.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):
bl_label = 'IFC Materials'