mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
Drawing cameras now save IfcBlock representations in IFC. See #1153.
This commit is contained in:
@@ -16,6 +16,7 @@ if bpy is not None:
|
|||||||
"unit": None,
|
"unit": None,
|
||||||
"georeference": None,
|
"georeference": None,
|
||||||
"context": None,
|
"context": None,
|
||||||
|
"drawing": None,
|
||||||
"attribute": None,
|
"attribute": None,
|
||||||
"type": None,
|
"type": None,
|
||||||
"spatial": None,
|
"spatial": None,
|
||||||
@@ -88,7 +89,6 @@ if bpy is not None:
|
|||||||
operator.RemoveVariable,
|
operator.RemoveVariable,
|
||||||
operator.PropagateTextData,
|
operator.PropagateTextData,
|
||||||
operator.SetOverrideColour,
|
operator.SetOverrideColour,
|
||||||
operator.AddDrawing,
|
|
||||||
operator.RemoveDrawing,
|
operator.RemoveDrawing,
|
||||||
operator.AddDrawingStyle,
|
operator.AddDrawingStyle,
|
||||||
operator.RemoveDrawingStyle,
|
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.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.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties)
|
||||||
bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
|
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.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties)
|
||||||
bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties)
|
bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties)
|
||||||
bpy.types.SCENE_PT_unit.append(ui.ifc_units)
|
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.Collection.BIMObjectProperties # Check if we need this
|
||||||
del bpy.types.Material.BIMMaterialProperties
|
del bpy.types.Material.BIMMaterialProperties
|
||||||
del bpy.types.Mesh.BIMMeshProperties
|
del bpy.types.Mesh.BIMMeshProperties
|
||||||
|
del bpy.types.Camera.BIMMeshProperties
|
||||||
del bpy.types.Camera.BIMCameraProperties
|
del bpy.types.Camera.BIMCameraProperties
|
||||||
del bpy.types.TextCurve.BIMTextProperties
|
del bpy.types.TextCurve.BIMTextProperties
|
||||||
bpy.types.SCENE_PT_unit.remove(ui.ifc_units)
|
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
|
self.settings[key] = value
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.evaluate_geometry()
|
if isinstance(self.settings["geometry"], bpy.types.Mesh):
|
||||||
|
self.evaluate_geometry()
|
||||||
if self.settings["unit_scale"] is None:
|
if self.settings["unit_scale"] is None:
|
||||||
self.settings["unit_scale"] = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
self.settings["unit_scale"] = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
||||||
if self.settings["context"].ContextType == "Model":
|
if self.settings["context"].ContextType == "Model":
|
||||||
@@ -130,6 +131,8 @@ class Usecase:
|
|||||||
return self.create_curve_representation()
|
return self.create_curve_representation()
|
||||||
elif self.settings["is_point_cloud"]:
|
elif self.settings["is_point_cloud"]:
|
||||||
return self.create_point_cloud_representation()
|
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":
|
elif self.settings["ifc_representation_class"] == "IfcExtrudedAreaSolid/IfcRectangleProfileDef":
|
||||||
return self.create_rectangle_extrusion_representation()
|
return self.create_rectangle_extrusion_representation()
|
||||||
elif self.settings["ifc_representation_class"] == "IfcExtrudedAreaSolid/IfcCircleProfileDef":
|
elif self.settings["ifc_representation_class"] == "IfcExtrudedAreaSolid/IfcCircleProfileDef":
|
||||||
@@ -138,6 +141,42 @@ class Usecase:
|
|||||||
return self.create_arbitrary_extrusion_representation()
|
return self.create_arbitrary_extrusion_representation()
|
||||||
return self.create_mesh_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):
|
def create_curve3d_representation(self):
|
||||||
return self.file.createIfcShapeRepresentation(
|
return self.file.createIfcShapeRepresentation(
|
||||||
self.settings["context"],
|
self.settings["context"],
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class AssignClass(bpy.types.Operator):
|
|||||||
elif self.predefined_type == "":
|
elif self.predefined_type == "":
|
||||||
predefined_type = None
|
predefined_type = None
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
if obj.data:
|
if obj.data and hasattr(obj.data, "materials"):
|
||||||
for material in obj.data.materials:
|
for material in obj.data.materials:
|
||||||
if not material.BIMMaterialProperties.ifc_style_id:
|
if not material.BIMMaterialProperties.ifc_style_id:
|
||||||
bpy.ops.bim.add_style(material=material.name)
|
bpy.ops.bim.add_style(material=material.name)
|
||||||
|
|||||||
@@ -1432,35 +1432,6 @@ class ActivateDrawingStyle(bpy.types.Operator):
|
|||||||
return space
|
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):
|
class RemoveDrawing(bpy.types.Operator):
|
||||||
bl_idname = "bim.remove_drawing"
|
bl_idname = "bim.remove_drawing"
|
||||||
bl_label = "Remove Drawing"
|
bl_label = "Remove Drawing"
|
||||||
|
|||||||
Reference in New Issue
Block a user