Fix #5541. Creating an object from a mesh now separates by loose parts to prevent unwanted vertex fusing.

This commit is contained in:
Dion Moult
2024-10-08 11:30:40 +11:00
parent a4226369bd
commit 29d6d2ba97
2 changed files with 30 additions and 8 deletions
@@ -377,16 +377,18 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator):
if representation_template == "EMTPY" or not ifc_context:
pass
elif representation_template == "OBJ" and not props.representation_obj:
pass
elif representation_template == "OBJ":
elif representation_template == "OBJ" and props.representation_obj:
obj.matrix_world = props.representation_obj.matrix_world
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
verts = [v.co / unit_scale for v in props.representation_obj.data.vertices]
faces = [p.vertices[:] for p in props.representation_obj.data.polygons]
item = builder.mesh(verts, faces)
representation = builder.get_representation(ifc_context, [item])
items = []
meshes = tool.Geometry.split_by_loose_parts(props.representation_obj)
for mesh in meshes:
verts = [v.co / unit_scale for v in mesh.vertices]
faces = [p.vertices[:] for p in mesh.polygons]
items.append(builder.mesh(verts, faces))
bpy.data.meshes.remove(mesh)
representation = builder.get_representation(ifc_context, items)
ifcopenshell.api.geometry.assign_representation(tool.Ifc.get(), element, representation)
bonsai.core.geometry.switch_representation(
tool.Ifc,
+21 -1
View File
@@ -47,7 +47,7 @@ from collections import defaultdict
from math import radians, pi
from mathutils import Vector, Matrix
from bonsai.bim.ifc import IfcStore
from typing import Union, Iterable, Optional, Literal, Iterator
from typing import Union, Iterable, Optional, Literal, Iterator, List
from typing_extensions import TypeIs
@@ -1562,3 +1562,23 @@ class Geometry(bonsai.core.tool.Geometry):
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), item)
obj.data.BIMMeshProperties.ifc_definition_id = new_item.id()
cls.reload_representation(bpy.context.scene.BIMGeometryProperties.representation_obj)
@classmethod
def split_by_loose_parts(cls, obj: bpy.types.Object) -> List[bpy.types.Mesh]:
dup_obj = obj.copy()
dup_obj.data = obj.data.copy()
bpy.context.scene.collection.objects.link(dup_obj)
tool.Blender.select_and_activate_single_object(bpy.context, dup_obj)
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.select_all(action="SELECT")
bpy.ops.mesh.separate(type="LOOSE")
bpy.ops.object.mode_set(mode="OBJECT")
results = []
for obj in bpy.context.selected_objects:
results.append(obj.data)
bpy.data.objects.remove(obj)
return results