Seems to be a refresh issue. Because of the grouping of many mesh faces. If you select on anything they are stll grouped together.
The result of MeshSplit has to stay selected, just like when surfaces are split.
@scottd , what about SubSurface splitting? Maybe to be implemented in WIP ?
# SubSurface split
import Rhino
import scriptcontext as sc
import System
from Rhino.Input.Custom import GetObject
from Rhino.DocObjects import ObjectType
def select_subfaces():
go = GetObject()
go.SetCommandPrompt("Select sub-surfaces (faces) of polysurfaces to split (Ctrl+Shift for faces)")
go.GeometryFilter = ObjectType.Surface
go.SubObjectSelect = True
go.GroupSelect = True
go.EnablePreSelect(True, True)
go.EnableClearObjectsOnEntry(False)
go.EnableUnselectObjectsOnExit(False)
go.DeselectAllBeforePostSelect = False
rc = go.GetMultiple(1, 0)
if rc != Rhino.Input.GetResult.Object:
return None
refs = []
for i in range(go.ObjectCount):
r = go.Object(i)
if r is None:
continue
# must be a face reference
if r.Face() is not None:
refs.append(r)
return refs
def select_cutters():
go = GetObject()
go.SetCommandPrompt("Select cutter surfaces/polysurfaces")
go.GeometryFilter = ObjectType.Surface | ObjectType.PolysrfFilter
go.SubObjectSelect = False
go.GroupSelect = True
go.EnablePreSelect(True, True)
go.EnableClearObjectsOnEntry(False)
go.EnableUnselectObjectsOnExit(False)
go.DeselectAllBeforePostSelect = False
rc = go.GetMultiple(1, 0)
if rc != Rhino.Input.GetResult.Object:
return None
cutters = []
for i in range(go.ObjectCount):
r = go.Object(i)
if r is None:
continue
brep = r.Brep()
if brep is None:
srf = r.Surface()
if srf is not None:
brep = srf.ToBrep()
if brep is not None:
cutters.append(brep)
return cutters
def try_join(breps, tol):
# RhinoCommon wants IEnumerable<Brep>
if not breps:
return None
joined = Rhino.Geometry.Brep.JoinBreps(breps, tol)
if joined and len(joined) > 0:
return list(joined)
return None
def main():
doc = sc.doc
tol = doc.ModelAbsoluteTolerance
face_refs = select_subfaces()
if not face_refs:
print("No faces selected.")
return
cutter_breps = select_cutters()
if not cutter_breps:
print("No cutters selected.")
return
# Group selected faces by their parent object id, with face indices
faces_by_obj = {} # Guid -> set(faceIndex)
for r in face_refs:
obj_id = r.ObjectId
face = r.Face()
if face is None:
continue
fi = face.FaceIndex
if obj_id not in faces_by_obj:
faces_by_obj[obj_id] = set()
faces_by_obj[obj_id].add(fi)
new_ids = []
replaced = 0
failed = 0
multi_out = 0
for obj_id, face_indices in faces_by_obj.items():
rh_obj = doc.Objects.FindId(obj_id)
if rh_obj is None:
failed += 1
continue
brep = rh_obj.Geometry
if not isinstance(brep, Rhino.Geometry.Brep):
failed += 1
continue
# Build a list of face-breps:
# - unselected faces: keep as-is (duplicate face)
# - selected faces: split and use resulting pieces
parts = []
try:
face_count = brep.Faces.Count
except:
failed += 1
continue
for i in range(face_count):
f = brep.Faces[i]
face_brep = f.DuplicateFace(True) # keeps trims
if face_brep is None:
continue
if i in face_indices:
split_pieces = face_brep.Split(cutter_breps, tol)
if split_pieces and len(split_pieces) > 0:
parts.extend(list(split_pieces))
else:
# no split -> keep original face
parts.append(face_brep)
else:
parts.append(face_brep)
# Join back into polysurface (or surface)
joined = try_join(parts, tol)
if joined is None or len(joined) == 0:
failed += 1
continue
# Best case: single joined Brep -> replace original
if len(joined) == 1:
new_brep = joined[0]
ok = doc.Objects.Replace(obj_id, new_brep)
if ok:
replaced += 1
new_ids.append(obj_id) # same id after replace
else:
# fallback: delete+add (keeps result even if replace fails)
attrs = rh_obj.Attributes.Duplicate()
doc.Objects.Delete(rh_obj, True)
gid = doc.Objects.AddBrep(new_brep, attrs)
if gid and gid != System.Guid.Empty:
new_ids.append(gid)
replaced += 1
else:
failed += 1
continue
# If join returns multiple Breps, we can't keep it as "one polysurface".
# We'll delete the original and add all pieces (still valid geometry, just not one Brep).
multi_out += 1
attrs = rh_obj.Attributes.Duplicate()
doc.Objects.Delete(rh_obj, True)
for jb in joined:
gid = doc.Objects.AddBrep(jb, attrs)
if gid and gid != System.Guid.Empty:
new_ids.append(gid)
if new_ids:
doc.Objects.UnselectAll()
for gid in new_ids:
doc.Objects.Select(gid, True)
doc.Views.Redraw()
print("Done.")
print(" Polysurfaces processed: {}".format(len(faces_by_obj)))
print(" Successfully replaced/updated: {}".format(replaced))
if multi_out:
print(" NOTE: {} object(s) produced multiple Breps after join; original was replaced by multiple objects.".format(multi_out))
if failed:
print(" Failures: {}".format(failed))
if __name__ == "__main__":
main()