I’ve got a brep made up of separate joined Polysurfaces. I’m trying to get the separate polysurfaces using Brep.GetConnectedComponents() but I get 6 separate surfaces instead of the 3 separate polysurfaces I would expect. Am I missing something?
import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
def TestSplit():
obj = rs.GetObjects()
if not obj:
return
brep = rs.coercebrep(obj)
breps = brep.GetConnectedComponents()
for i in breps:
sc.doc.Objects.AddBrep(i)
rs.DeleteObject(obj)
TestSplit()
Hi @603419608 , the example I gave just highlights the problem with the method not working as expected. I know I could just explode and join, but I need to return the separate brep parts without changing them like JoinBreps() does. I have polysurfaces with faces pointing in different direction like so:
I’d like to retrieve each separate polysurface without changing the direction of each face. I guess I should have mentioned that being problem I’m trying to solve. Here’s the file with the faces pointing in different direction: 220813 GetConnectedComp 2.3dm (194.9 KB)
Brep.GetConnectedComponents is returning 6 monoface breps because all the of the original brep’s edges are naked.
This script can separate the breps of joinable sets of faces.
import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
def TestSplit():
obj = rs.GetObject(preselect=True)
if not obj:
return
brep_In = rs.coercebrep(obj)
brep_TaggedSrfs = brep_In.DuplicateBrep()
key = '_FaceIndex'
for face in brep_TaggedSrfs.Faces:
face.UnderlyingSurface().SetUserString(key, str(face.FaceIndex))
breps_GCC = brep_TaggedSrfs.GetConnectedComponents()
if len(breps_GCC) < 2:
print "Brep does not have multiple 'shells'."
return
breps_Joined = Rhino.Geometry.Brep.JoinBreps(
breps_GCC, 2.0*sc.doc.ModelAbsoluteTolerance)
if len(breps_Joined) < 2:
print "Brep does not have multiple 'shells'."
return
bDeleteOK = True
for brep in breps_Joined:
idxs = [int(face.UnderlyingSurface().GetUserString(key))
for face in brep.Faces]
brep_Out = brep_In.DuplicateBrep()
for i in xrange(brep_In.Faces.Count-1, -1, -1):
if i in idxs: continue
brep_Out.Faces.RemoveAt(i)
gOut = sc.doc.Objects.AddBrep(brep_Out)
if gOut == gOut.Empty:
print "Subset of brep could not be added."
bDeleteOK = False
if bDeleteOK: rs.DeleteObject(obj)
sc.doc.Views.Redraw()
TestSplit()
Good point! Thanks! Do you know if there’s a way to joining those polysurfaces without getting any naked edges in the touching edges and while keeping their face direction? @spb
_NonmanifoldMerge and Brep.MergeBreps Method will do it, although the latter creates invalid breps with your geometry that can be repaired with Brep.Repair.
Script with MergeBreps
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
import scriptcontext as sc
def TestSplit():
obj = rs.GetObject(preselect=True)
if not obj:
return
brep_In = rs.coercebrep(obj)
brep_TaggedSrfs = brep_In.DuplicateBrep()
key = '_FaceIndex'
for face in brep_TaggedSrfs.Faces:
face.UnderlyingSurface().SetUserString(key, str(face.FaceIndex))
breps_GCC = brep_TaggedSrfs.GetConnectedComponents()
if len(breps_GCC) < 2:
print "Brep does not have multiple 'shells'."
return
breps_Joined = rg.Brep.JoinBreps(
breps_GCC, 2.0*sc.doc.ModelAbsoluteTolerance)
if len(breps_Joined) < 2:
print "Brep does not have multiple 'shells'."
return
bDeleteOK = True
for brep in breps_Joined:
idxs = [int(face.UnderlyingSurface().GetUserString(key))
for face in brep.Faces]
breps_ToMerge = [rg.BrepFace.DuplicateFace(
brep_In.Faces[i], duplicateMeshes=True)
for i in xrange(brep_In.Faces.Count)
if i in idxs]
brep_Out = rg.Brep.MergeBreps(
breps_ToMerge,
2.0*sc.doc.ModelAbsoluteTolerance)
bValid, sLog = brep_Out.IsValidWithLog()
if not bValid:
#print sLog
if brep_Out.Repair(sc.doc.ModelAbsoluteTolerance):
#print "Brep.Repair succeeded."
pass
else:
print "Brep.Repair failed."
bDeleteOK = False
continue
gOut = sc.doc.Objects.AddBrep(brep_Out)
if gOut == gOut.Empty:
print "Subset of brep could not be added."
bDeleteOK = False
if bDeleteOK: rs.DeleteObject(obj)
sc.doc.Views.Redraw()
TestSplit()