Drawing cameras now save IfcBlock representations in IFC. See #1153.

This commit is contained in:
Dion Moult
2021-03-04 22:04:40 +11:00
parent d2d4a1b976
commit 29f64f7c11
6 changed files with 91 additions and 32 deletions
@@ -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)
@@ -0,0 +1,14 @@
import bpy
from . import operator
classes = (
operator.AddDrawing,
)
def register():
pass
def unregister():
pass
@@ -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"}
@@ -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"],
@@ -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)
@@ -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"