mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
Bonsai: fix the same duplicate-loop vertex-group bug in auto_detect_curves
auto_detect_profiles had the identical defect fixed in the previous commit: duplicating a circle/arc loop in Edit Mode reuses the same IFCCIRCLE/IFCARCINDEX vertex group index for the new geometry, and this sibling function (used for curve/annotation editing rather than profile voids) tallied group membership across the whole mesh instead of per loop, so it also rejected a legitimately duplicated loop as malformed. Applied the identical fix: scope the group-count sanity check to each connected edge loop, computed after the loops are built rather than in the initial whole-mesh vertex pass. Kept the existing forked-loop check (more than 2 edges per vertex) in the first pass since it is unrelated to group counting. Verified live in headless Blender: constructed two 2-vertex IFCCIRCLE loops sharing one vertex group index (the exact state Blender's Edit Mode duplicate produces) and called auto_detect_curves directly. Before this change it returned (False, "CIRCLE"); after, it returns two valid IfcCircle curves. Generated with the assistance of an AI coding tool.
This commit is contained in:
committed by
Dion Moult
parent
0a027d47a3
commit
0d5ea02169
@@ -2528,27 +2528,11 @@ class Model(bonsai.core.tool.Model):
|
||||
deform_layer = bm.verts.layers.deform.active
|
||||
|
||||
# Sanity check
|
||||
group_verts = {"IFCARCINDEX": {}, "IFCCIRCLE": {}}
|
||||
if deform_layer:
|
||||
for vert in bm.verts:
|
||||
vert_group_indices = tool.Blender.bmesh_get_vertex_groups(vert, deform_layer)
|
||||
for group_index in vert_group_indices:
|
||||
group_type = "IFCARCINDEX" if group_index in groups["IFCARCINDEX"] else "IFCCIRCLE"
|
||||
group_verts[group_type].setdefault(group_index, 0)
|
||||
group_verts[group_type][group_index] += 1
|
||||
if len(vert.link_edges) > 2: # Forked loop
|
||||
return (False, "FORKED_LOOP")
|
||||
|
||||
for group_type, group_counts in group_verts.items():
|
||||
if group_type == "IFCARCINDEX":
|
||||
for group_count in group_counts.values():
|
||||
if group_count != 3: # Each arc needs 3 verts
|
||||
return (False, "3POINT_ARC")
|
||||
elif group_type == "IFCCIRCLE":
|
||||
for group_count in group_counts.values():
|
||||
if group_count != 2: # Each circle needs 2 verts
|
||||
return (False, "CIRCLE")
|
||||
|
||||
loop_edges = list(bm.edges)
|
||||
|
||||
# Create loops from edges
|
||||
@@ -2571,6 +2555,28 @@ class Model(bonsai.core.tool.Model):
|
||||
has_found_connected_edge = True
|
||||
loops.append(loop)
|
||||
|
||||
# Sanity check, per loop rather than across the whole mesh
|
||||
if deform_layer:
|
||||
for loop in loops:
|
||||
loop_group_counts = {"IFCARCINDEX": {}, "IFCCIRCLE": {}}
|
||||
loop_verts = {v for edge in loop for v in edge.verts}
|
||||
for vert in loop_verts:
|
||||
for group_index in tool.Blender.bmesh_get_vertex_groups(vert, deform_layer):
|
||||
if group_index in groups["IFCARCINDEX"]:
|
||||
group_type = "IFCARCINDEX"
|
||||
elif group_index in groups["IFCCIRCLE"]:
|
||||
group_type = "IFCCIRCLE"
|
||||
else:
|
||||
continue
|
||||
loop_group_counts[group_type].setdefault(group_index, 0)
|
||||
loop_group_counts[group_type][group_index] += 1
|
||||
for group_count in loop_group_counts["IFCARCINDEX"].values():
|
||||
if group_count != 3: # Each arc needs 3 verts
|
||||
return (False, "3POINT_ARC")
|
||||
for group_count in loop_group_counts["IFCCIRCLE"].values():
|
||||
if group_count != 2: # Each circle needs 2 verts
|
||||
return (False, "CIRCLE")
|
||||
|
||||
tmp = ifcopenshell.file(schema=tool.Ifc.get().schema)
|
||||
|
||||
def is_in_group(v: bmesh.types.BMVert, group_name: str) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user