diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index f04196d547..e8346c5622 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -16,6 +16,7 @@ if bpy is not None: "unit": None, "georeference": None, "context": None, + "drawing": None, "attribute": None, "type": None, "spatial": None, @@ -88,7 +89,6 @@ if bpy is not None: operator.RemoveVariable, operator.PropagateTextData, operator.SetOverrideColour, - operator.AddDrawing, operator.RemoveDrawing, operator.AddDrawingStyle, operator.RemoveDrawingStyle, @@ -182,6 +182,7 @@ if bpy is not None: bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) # Check if we need this bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties) bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) + bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties) bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties) bpy.types.SCENE_PT_unit.append(ui.ifc_units) @@ -208,6 +209,7 @@ if bpy is not None: del bpy.types.Collection.BIMObjectProperties # Check if we need this del bpy.types.Material.BIMMaterialProperties del bpy.types.Mesh.BIMMeshProperties + del bpy.types.Camera.BIMMeshProperties del bpy.types.Camera.BIMCameraProperties del bpy.types.TextCurve.BIMTextProperties bpy.types.SCENE_PT_unit.remove(ui.ifc_units) diff --git a/src/ifcblenderexport/blenderbim/bim/module/drawing/__init__.py b/src/ifcblenderexport/blenderbim/bim/module/drawing/__init__.py new file mode 100644 index 0000000000..998cb5f006 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/drawing/__init__.py @@ -0,0 +1,14 @@ +import bpy +from . import operator + +classes = ( + operator.AddDrawing, +) + + +def register(): + pass + + +def unregister(): + pass diff --git a/src/ifcblenderexport/blenderbim/bim/module/drawing/operator.py b/src/ifcblenderexport/blenderbim/bim/module/drawing/operator.py new file mode 100644 index 0000000000..a6f7f3663a --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/drawing/operator.py @@ -0,0 +1,33 @@ +import bpy +from blenderbim.bim.ifc import IfcStore + + +class AddDrawing(bpy.types.Operator): + bl_idname = "bim.add_drawing" + bl_label = "Add Drawing" + + def execute(self, context): + new = context.scene.DocProperties.drawings.add() + new.name = "DRAWING {}".format(len(context.scene.DocProperties.drawings)) + if not bpy.data.collections.get("Views"): + 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(new.name, bpy.data.cameras.new(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.clip_end = 10 # A slightly more reasonable default + if context.scene.unit_settings.system == "IMPERIAL": + camera.data.BIMCameraProperties.diagram_scale = '1/8"=1\'-0"|1/96' + else: + camera.data.BIMCameraProperties.diagram_scale = "1:100|1/100" + context.scene.camera = camera + view_collection.objects.link(camera) + area = next(area for area in context.screen.areas if area.type == "VIEW_3D") + area.spaces[0].region_3d.view_perspective = "CAMERA" + new.camera = camera + bpy.ops.bim.assign_class(obj=camera.name, ifc_class="IfcAnnotation") + bpy.ops.bim.activate_drawing_style() + return {"FINISHED"} diff --git a/src/ifcblenderexport/blenderbim/bim/module/geometry/add_representation.py b/src/ifcblenderexport/blenderbim/bim/module/geometry/add_representation.py index 0310719317..ea7ab0ffce 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/geometry/add_representation.py +++ b/src/ifcblenderexport/blenderbim/bim/module/geometry/add_representation.py @@ -32,7 +32,8 @@ class Usecase: self.settings[key] = value def execute(self): - self.evaluate_geometry() + if isinstance(self.settings["geometry"], bpy.types.Mesh): + self.evaluate_geometry() if self.settings["unit_scale"] is None: self.settings["unit_scale"] = ifcopenshell.util.unit.calculate_unit_scale(self.file) if self.settings["context"].ContextType == "Model": @@ -130,6 +131,8 @@ class Usecase: return self.create_curve_representation() elif self.settings["is_point_cloud"]: return self.create_point_cloud_representation() + elif isinstance(self.settings["geometry"], bpy.types.Camera): + return self.create_camera_block_representation() elif self.settings["ifc_representation_class"] == "IfcExtrudedAreaSolid/IfcRectangleProfileDef": return self.create_rectangle_extrusion_representation() elif self.settings["ifc_representation_class"] == "IfcExtrudedAreaSolid/IfcCircleProfileDef": @@ -138,6 +141,42 @@ class Usecase: return self.create_arbitrary_extrusion_representation() return self.create_mesh_representation() + def create_camera_block_representation(self): + raster_x = self.settings["geometry"].BIMCameraProperties.raster_x + raster_y = self.settings["geometry"].BIMCameraProperties.raster_y + + if self.is_camera_landscape(): + width = self.settings["geometry"].ortho_scale + height = width / raster_x * raster_y + else: + height = self.settings["geometry"].ortho_scale + width = height / raster_y * raster_x + + block = self.file.create_entity( + "IfcBlock", + **{ + "Position": self.file.createIfcAxis2Placement3D( + self.create_cartesian_point(-width / 2, -height / 2, -self.settings["geometry"].clip_end) + ), + "XLength": self.convert_si_to_unit(width), + "YLength": self.convert_si_to_unit(height), + "ZLength": self.convert_si_to_unit(self.settings["geometry"].clip_end), + } + ) + + return self.file.createIfcShapeRepresentation( + self.settings["context"], + self.settings["context"].ContextIdentifier, + "CSG", + [self.file.createIfcCsgSolid(block)], + ) + + def is_camera_landscape(self): + return ( + self.settings["geometry"].BIMCameraProperties.raster_x + > self.settings["geometry"].BIMCameraProperties.raster_y + ) + def create_curve3d_representation(self): return self.file.createIfcShapeRepresentation( self.settings["context"], diff --git a/src/ifcblenderexport/blenderbim/bim/module/root/operator.py b/src/ifcblenderexport/blenderbim/bim/module/root/operator.py index dbf11855be..7eda7f3a96 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/root/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/module/root/operator.py @@ -93,7 +93,7 @@ class AssignClass(bpy.types.Operator): elif self.predefined_type == "": predefined_type = None for obj in objects: - if obj.data: + if obj.data and hasattr(obj.data, "materials"): for material in obj.data.materials: if not material.BIMMaterialProperties.ifc_style_id: bpy.ops.bim.add_style(material=material.name) diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index da701ce54a..edea521878 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -1432,35 +1432,6 @@ class ActivateDrawingStyle(bpy.types.Operator): return space -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 - if bpy.context.scene.unit_settings.system == "IMPERIAL": - camera.data.BIMCameraProperties.diagram_scale = '1/8"=1\'-0"|1/96' - else: - camera.data.BIMCameraProperties.diagram_scale = "1:100|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 - bpy.ops.bim.activate_drawing_style() - return {"FINISHED"} - - class RemoveDrawing(bpy.types.Operator): bl_idname = "bim.remove_drawing" bl_label = "Remove Drawing"