In the file below, there is another one of my bad volumes.
FixBadBrep.3dm (2.7 MB)
If one simply runs Explode - you will get a bad object warning if you have CheckNewObjects turned on - and then Join, you will end up with one good, closed polysurface and one bad surface which you can delete.
Now, if I try to do it script-wise - I can mimic the procedure with rhinoscriptsyntax and rs.Command()
:
import rhinoscriptsyntax as rs
def ExplodeRejoinObject(obj_id,tol=sc.doc.ModelAbsoluteTolerance):
rs.UnselectAllObjects()
rs.SelectObject(obj_id)
rs.Command("_Explode",False)
lco=rs.LastCreatedObjects()
rs.UnselectAllObjects()
rs.SelectObjects(lco)
rs.Command("_Join",False)
return rs.LastCreatedObjects()
obj_id=rs.GetObject("Select a polysurface",16,preselect=True)
if obj_id:
rs.EnableRedraw(False)
result=ExplodeRejoinObject(obj_id)
if result:
solid_count=0
for item in result:
if rs.IsObjectSolid(item):
solid_count+=1
else:
rs.DeleteObject(item)
if solid_count>0:
rs.DeleteObject(obj_id)
The main problem is that the CheckNewObjects dialog will come up and stop the script until I hit OK. So I need to turn it off if I wnat the script to run to completion without having to do this. But, because of this issue, I have no way of knowing if it was turned on before, so if I automatically turn it back on after the script ends, that is maybe unwanted by the user. But it does succe
So, I tried to duplicate what it does with RhinoCommon and avoid the CheckNewObjects coming up by hopefully eliminating invalid objects before I add them to the document, but I was spectacularly unsuccessful up to now.
So for example just trying to explode and rejoin via RhinoCommon, but it fails to create a solid.
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def ExplodeRejoinBrep(brep,tol=sc.doc.ModelAbsoluteTolerance):
face_coll=[face.DuplicateFace(False) for face in brep.Faces]
joined=Rhino.Geometry.Brep.JoinBreps(face_coll,tol)
return joined
obj_id=rs.GetObject("Select a polysurface",16,preselect=True)
if obj_id:
obj=rs.coercebrep(obj_id)
br_fix=ExplodeRejoinBrep(obj)
if br_fix:
solid_count=0
for brep in br_fix:
if brep.IsValid:
sc.doc.Objects.AddBrep(brep)
solid_count+=1
print("{} solids added to doc".format(solid_count))
sc.doc.Views.Redraw()
I get two valid open breps and one invalid one.
I also tried with Brep.CreateSolid
:
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def ExplodeCreateSolidBrep(brep,tol=sc.doc.ModelAbsoluteTolerance):
face_coll=[face.DuplicateFace(False) for face in brep.Faces]
cs=Rhino.Geometry.Brep.CreateSolid(face_coll,tol)
return cs
obj_id=rs.GetObject("Select a polysurface",16,preselect=True)
if obj_id:
obj=rs.coercebrep(obj_id)
br_fix=ExplodeCreateSolidBrep(obj)
if br_fix:
solid_count=0
for brep in br_fix:
if brep.IsValid and brep.IsSolid:
sc.doc.Objects.AddBrep(brep)
solid_count+=1
print("{} solids added to doc".format(solid_count))
sc.doc.Views.Redraw()
This makes a solid, but unfortunately it is invalid again.
So what does native Join magically do that I can’t do in RhinoCommon? I have a feeling it allows for joining of edges that are further out of tolerance than the file tolerance.