mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Reimplement roundtrip of most annotation elements for drawings. See #1153.
This commit is contained in:
@@ -809,6 +809,9 @@ class IfcImporter:
|
||||
elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
|
||||
mesh = self.create_camera(element, shape)
|
||||
self.link_mesh(shape, mesh)
|
||||
elif element.is_a("IfcAnnotation") and self.is_curve_annotation(element):
|
||||
mesh = self.create_curve(element, shape)
|
||||
self.link_mesh(shape, mesh)
|
||||
elif shape:
|
||||
mesh_name = self.get_mesh_name(shape.geometry)
|
||||
mesh = self.meshes.get(mesh_name)
|
||||
@@ -950,6 +953,34 @@ class IfcImporter:
|
||||
curve.bevel_depth = self.unit_scale * item.Radius
|
||||
return curve
|
||||
|
||||
def create_native_annotation(self, element, mesh_name):
|
||||
# TODO: georeferencing?
|
||||
curve = bpy.data.curves.new(mesh_name, type="CURVE")
|
||||
curve.dimensions = "3D"
|
||||
curve.resolution_u = 2
|
||||
polyline = curve.splines.new("POLY")
|
||||
|
||||
for representation in self.native_data[element.GlobalId]["representations"]:
|
||||
for item in representation["raw"].Items:
|
||||
# TODO: support inner radius, start param, and end param
|
||||
geometry = ifcopenshell.geom.create_shape(self.settings_native, item.Directrix)
|
||||
e = geometry.edges
|
||||
v = geometry.verts
|
||||
vertices = [[v[i], v[i + 1], v[i + 2], 1] for i in range(0, len(v), 3)]
|
||||
edges = [[e[i], e[i + 1]] for i in range(0, len(e), 2)]
|
||||
v2 = None
|
||||
for edge in edges:
|
||||
v1 = vertices[edge[0]]
|
||||
if v1 != v2:
|
||||
polyline = curve.splines.new("POLY")
|
||||
polyline.points[-1].co = representation["matrix"] @ mathutils.Vector(v1)
|
||||
v2 = vertices[edge[1]]
|
||||
polyline.points.add(1)
|
||||
polyline.points[-1].co = representation["matrix"] @ mathutils.Vector(v2)
|
||||
|
||||
curve.bevel_depth = self.unit_scale * item.Radius
|
||||
return curve
|
||||
|
||||
def merge_by_class(self):
|
||||
merge_set = {}
|
||||
for obj in self.added_data.values():
|
||||
@@ -1098,6 +1129,7 @@ class IfcImporter:
|
||||
def create_spatial_decomposition_collections(self):
|
||||
for rel_aggregate in self.project["ifc"].IsDecomposedBy or []:
|
||||
self.create_spatial_decomposition_collection(self.project["blender"], rel_aggregate.RelatedObjects)
|
||||
self.create_views_collection()
|
||||
self.create_type_collection()
|
||||
|
||||
def create_type_collection(self):
|
||||
@@ -1109,6 +1141,22 @@ class IfcImporter:
|
||||
self.type_collection = bpy.data.collections.new("Types")
|
||||
self.project["blender"].children.link(self.type_collection)
|
||||
|
||||
def create_views_collection(self):
|
||||
view_collection = None
|
||||
for collection in self.project["blender"].children:
|
||||
if collection.name == "Views":
|
||||
view_collection = collection
|
||||
break
|
||||
if not view_collection:
|
||||
view_collection = bpy.data.collections.new("Views")
|
||||
self.project["blender"].children.link(view_collection)
|
||||
for element in self.file.by_type("IfcAnnotation"):
|
||||
if element.ObjectType == "DRAWING":
|
||||
group = [r for r in element.HasAssignments if r.is_a("IfcRelAssignsToGroup")][0].RelatingGroup
|
||||
collection = bpy.data.collections.new("IfcGroup/" + group.Name)
|
||||
self.collections[group.GlobalId] = collection
|
||||
view_collection.children.link(collection)
|
||||
|
||||
def create_spatial_decomposition_collection(self, parent, related_objects):
|
||||
for element in related_objects:
|
||||
if element not in self.spatial_elements:
|
||||
@@ -1251,16 +1299,9 @@ class IfcImporter:
|
||||
return self.structural_member_collection.objects.link(obj)
|
||||
elif element.is_a("IfcStructuralConnection"):
|
||||
return self.structural_connection_collection.objects.link(obj)
|
||||
elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
|
||||
view_collection = bpy.data.collections.get("Views")
|
||||
if not view_collection:
|
||||
view_collection = bpy.data.collections.new("Views")
|
||||
bpy.context.scene.collection.children.link(view_collection)
|
||||
elif element.is_a("IfcAnnotation") and self.is_drawing_annotation(element):
|
||||
group = [r for r in element.HasAssignments if r.is_a("IfcRelAssignsToGroup")][0].RelatingGroup
|
||||
drawing_collection = bpy.data.collections.new("IfcGroup/" + group.Name)
|
||||
view_collection.children.link(drawing_collection)
|
||||
drawing_collection.objects.link(obj)
|
||||
return
|
||||
return self.collections[group.GlobalId].objects.link(obj)
|
||||
|
||||
container = ifcopenshell.util.element.get_container(element)
|
||||
if container:
|
||||
@@ -1276,6 +1317,31 @@ class IfcImporter:
|
||||
self.ifc_import_settings.logger.warning("Warning: this object is outside the spatial hierarchy %s", element)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
|
||||
def is_curve_annotation(self, element):
|
||||
return element.ObjectType in [
|
||||
"DIMENSION",
|
||||
"EQUAL_DIMENSION",
|
||||
"LEVEL",
|
||||
"STAIR_ARROW",
|
||||
"TEXT_LEADER",
|
||||
"MISC",
|
||||
]
|
||||
|
||||
def is_drawing_annotation(self, element):
|
||||
return element.ObjectType in [
|
||||
"BREAKLINE",
|
||||
"DIMENSION",
|
||||
"DRAWING",
|
||||
"EQUAL_DIMENSION",
|
||||
"GRID",
|
||||
"HIDDEN_LINE",
|
||||
"LEVEL",
|
||||
"MISC",
|
||||
"STAIR_ARROW",
|
||||
"TEXT",
|
||||
"TEXT_LEADER",
|
||||
]
|
||||
|
||||
def get_element_matrix(self, element):
|
||||
result = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
||||
result[0][3] *= self.unit_scale
|
||||
@@ -1402,6 +1468,31 @@ class IfcImporter:
|
||||
camera.BIMCameraProperties.custom_diagram_scale = pset["Scale"]
|
||||
return camera
|
||||
|
||||
def create_curve(self, element, shape):
|
||||
if hasattr(shape, "geometry"):
|
||||
geometry = shape.geometry
|
||||
else:
|
||||
geometry = shape
|
||||
|
||||
curve = bpy.data.curves.new(self.get_mesh_name(geometry), type="CURVE")
|
||||
curve.dimensions = "3D"
|
||||
curve.resolution_u = 2
|
||||
|
||||
e = geometry.edges
|
||||
v = geometry.verts
|
||||
vertices = [[v[i], v[i + 1], v[i + 2], 1] for i in range(0, len(v), 3)]
|
||||
edges = [[e[i], e[i + 1]] for i in range(0, len(e), 2)]
|
||||
v2 = None
|
||||
for edge in edges:
|
||||
v1 = vertices[edge[0]]
|
||||
if v1 != v2:
|
||||
polyline = curve.splines.new("POLY")
|
||||
polyline.points[-1].co = mathutils.Vector(v1)
|
||||
v2 = vertices[edge[1]]
|
||||
polyline.points.add(1)
|
||||
polyline.points[-1].co = mathutils.Vector(v2)
|
||||
return curve
|
||||
|
||||
def create_mesh(self, element, shape):
|
||||
try:
|
||||
if hasattr(shape, "geometry"):
|
||||
|
||||
Reference in New Issue
Block a user