mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
New UI to assign multiple swept solids per object
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user