diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 49ede60bd5..2b34993b95 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -11,6 +11,7 @@ if bpy is not None: from .module.covetool import ui as covetool_ui from .module.covetool import operator as covetool_operator + from .module.model import grid as model_grid from .module.model import wall as model_wall from .module.model import stair as model_stair from .module.model import door as model_door @@ -279,6 +280,7 @@ if bpy is not None: covetool_operator.Login, covetool_operator.RunSimpleAnalysis, covetool_operator.RunAnalysis, + model_grid.BIM_OT_add_object, model_wall.BIM_OT_add_object, model_stair.BIM_OT_add_object, model_door.BIM_OT_add_object, @@ -319,6 +321,7 @@ if bpy is not None: bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties) bpy.types.Scene.CoveToolProperties = bpy.props.PointerProperty(type=covetool_prop.CoveToolProperties) bpy.types.SCENE_PT_unit.append(ui.ifc_units) + bpy.types.VIEW3D_MT_mesh_add.append(model_grid.add_object_button) bpy.types.VIEW3D_MT_mesh_add.append(model_wall.add_object_button) bpy.types.VIEW3D_MT_mesh_add.append(model_stair.add_object_button) bpy.types.VIEW3D_MT_mesh_add.append(model_door.add_object_button) @@ -343,6 +346,7 @@ if bpy is not None: del(bpy.types.Camera.BIMCameraProperties) del(bpy.types.Camera.BIMTextProperties) bpy.types.SCENE_PT_unit.remove(ui.ifc_units) + bpy.types.VIEW3D_MT_mesh_add.remove(model_grid.add_object_button) bpy.types.VIEW3D_MT_mesh_add.remove(model_wall.add_object_button) bpy.types.VIEW3D_MT_mesh_add.remove(model_stair.add_object_button) bpy.types.VIEW3D_MT_mesh_add.remove(model_door.add_object_button) diff --git a/src/ifcblenderexport/blenderbim/bim/export_ifc.py b/src/ifcblenderexport/blenderbim/bim/export_ifc.py index 41399b0b83..9a667c75b9 100644 --- a/src/ifcblenderexport/blenderbim/bim/export_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/export_ifc.py @@ -1161,7 +1161,13 @@ class IfcParser(): grid_raw = bpy.data.objects.get(self.get_parent_collection(obj.users_collection[0]).name) if grid_raw.name not in results: results[grid_raw.name] = {'UAxes': [], 'VAxes': [], 'WAxes': []} - results[grid_raw.name][obj.users_collection[0].name].append ({ + if 'UAxes' in obj.users_collection[0].name: + axis_type = 'UAxes' + elif 'VAxes' in obj.users_collection[0].name: + axis_type = 'VAxes' + else: + axis_type = 'WAxes' + results[grid_raw.name][axis_type].append ({ 'ifc': None, 'raw': obj, 'grid_raw': grid_raw, diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index 9bf2dd403a..15c7449981 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -679,7 +679,10 @@ class IfcImporter(): def create_grids(self): grids = self.file.by_type('IfcGrid') for grid in grids: - grid_obj = self.create_product(grid, ifcopenshell.geom.create_shape(self.settings_2d, grid)) + shape = None + if grid.Representation: + shape = ifcopenshell.geom.create_shape(self.settings_2d, grid) + grid_obj = self.create_product(grid, shape) collection = bpy.data.collections.new(self.get_name(grid)) element_matrix = self.get_local_placement(grid.ObjectPlacement) element_matrix[0][3] *= self.unit_scale diff --git a/src/ifcblenderexport/blenderbim/bim/module/model/grid.py b/src/ifcblenderexport/blenderbim/bim/module/model/grid.py new file mode 100644 index 0000000000..4e33e69962 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/model/grid.py @@ -0,0 +1,74 @@ +import bpy +import math +from bpy.types import Operator +from bpy.props import FloatVectorProperty, FloatProperty, IntProperty +from bpy_extras.object_utils import AddObjectHelper, object_data_add +from mathutils import Vector + +def add_object(self, context): + obj = object_data_add(context, None, operator=self) + obj.name = 'IfcGrid/Grid' + name = obj.name.split('/')[1] + + default_collection = obj.users_collection[0] + default_collection.objects.unlink(obj) + + collection = bpy.data.collections.new('IfcGrid/' + name) + bpy.context.view_layer.active_layer_collection.collection.children.link(collection) + collection.objects.link(obj) + + axes_collection = bpy.data.collections.new('UAxes') + collection.children.link(axes_collection) + for i in range(0, self.total_u): + verts = [Vector((-2, i*self.u_spacing, 0)), Vector((((self.total_v-1)*self.v_spacing)+2, i*self.u_spacing, 0))] + edges = [[0, 1]] + faces = [] + mesh = bpy.data.meshes.new(name="Grid Axis") + mesh.from_pydata(verts, edges, faces) + obj = object_data_add(context, mesh, operator=self) + tag = chr(ord('A')+i) + obj.name = 'IfcGridAxis/' + tag + default_collection.objects.unlink(obj) + axes_collection.objects.link(obj) + attribute = obj.BIMObjectProperties.attributes.add() + attribute.name = 'AxisTag' + attribute.string_value = tag + + axes_collection = bpy.data.collections.new('VAxes') + collection.children.link(axes_collection) + for i in range(0, self.total_v): + verts = [Vector((i*self.v_spacing, -2, 0)), Vector((i*self.v_spacing, ((self.total_u-1)*self.u_spacing)+2, 0))] + edges = [[0, 1]] + faces = [] + mesh = bpy.data.meshes.new(name="Grid Axis") + mesh.from_pydata(verts, edges, faces) + obj = object_data_add(context, mesh, operator=self) + tag = str(i+1).zfill(2) + obj.name = 'IfcGridAxis/' + tag + default_collection.objects.unlink(obj) + axes_collection.objects.link(obj) + attribute = obj.BIMObjectProperties.attributes.add() + attribute.name = 'AxisTag' + attribute.string_value = tag + + + +class BIM_OT_add_object(Operator, AddObjectHelper): + bl_idname = "mesh.add_grid" + bl_label = "Grid" + bl_options = {'REGISTER', 'UNDO'} + + u_spacing: FloatProperty(name='U Spacing', default=10) + total_u: IntProperty(name='Number of U Grids', default=3) + v_spacing: FloatProperty(name='V Spacing', default=10) + total_v: IntProperty(name='Number of V Grids', default=3) + + def execute(self, context): + add_object(self, context) + return {'FINISHED'} + + +def add_object_button(self, context): + self.layout.operator( + BIM_OT_add_object.bl_idname, + icon='PLUGIN')