I’ve had a lot of help in the past (thanks mainly to Helvetosaur) in writing a script which splits a solid into layers of constant thickness. Then it creates a silhouette outline on each layer from which I derive an offset outline (used for CNC machining the final solid when it’s all put back together). I’ve used this a lot, and it sometimes has trouble getting the silhouette for some shapes. But the latest solid I’m using it seems to fail with every layer. I don’t know if the shape is too complex, but there’s no benefit in using the script if it fails for all layers. And when it works, it’s wonderful and saves lots of time. I’ll copy the script in and the solid I’m using to see if anyone can help point out a way to make this more reliable. There’s a bit of other stuff going on in the script, but it’s the CreateOffsetOutlines which fails (it needs to be run taking the slices from the Top View as that’s what the machine and I do.
Thanks, Ben
Combined Slices and Outline.py (4.2 KB)
Test Model.3dm (5.3 MB)
I ran just the CreateOffsetOutlines
routine on your object and stopped after the creation of all the silhouette curves but before it got to the CreateBooleanRegions
part; I added the silhouette curves to the document to see what you were getting as input to CreateBooleanRegions
…
This is what I see:
Note the lower right hand corner:
Part of the silhouette is missing there, therefore CreateBooleanRegions
can’t find a complete outer region. This is odd because the native Rhino Silhouette command does find the complete outer outline… So something is either buggy in the Silhouette.Compute()...
for this object, or maybe some other problem… Will look a bit further.
Edit:
I cannot get it to work with RhinoCommon Silhouette.Compute(), no matter what options I tried, it still leaves that one corner out. To test I re-wrote the routine using rs.Command(“_Silhouette”) and that works… I don’t know what else to do at this point, I guess a bug report needs to be written up.
import Rhino
import Rhino.Geometry as rg
import rhinoscriptsyntax as rs
import scriptcontext
def CreateOffsetOutlineView(ObjectID,OffsetDistance):
rs.EnableRedraw(False)
#store current view
prev_view=rs.CurrentView()
#set top view for Silhouette command
rs.CurrentView("Top")
rs.UnselectAllObjects()
rs.SelectObject(ObjectID)
rs.Command("_Silhouette")
lco=rs.LastCreatedObjects()
if lco:
xform=rs.XformPlanarProjection(rg.Plane.WorldXY)
crv_ids=rs.TransformObjects(lco,xform)
if not crv_ids:
rs.DeleteObjects(lco)
return
tol=scriptcontext.doc.ModelAbsoluteTolerance
atol=scriptcontext.doc.ModelAngleToleranceRadians
crvs=[rs.coercecurve(crv_id) for crv_id in crv_ids]
rs.DeleteObjects(crv_ids)
regions = rg.Curve.CreateBooleanRegions(crvs,rg.Plane.WorldXY,True,tol)
a = regions.RegionCurves(0)
outline_id=scriptcontext.doc.Objects.AddCurve(a[0])
#restore previous current view
rs.CurrentView(prev_view)
if outline_id:
wz_vec=Rhino.Geometry.Plane.WorldXY.ZAxis
offset_id=rs.OffsetCurve(outline_id,[4000,4000,0],OffsetDistance,wz_vec)
rs.DeleteObject(outline_id)
if offset_id: return offset_id
obj_id=rs.GetObject("Select volume for offset outline",8+16,preselect=True)
test=CreateOffsetOutlineView(obj_id,10)
print test
1 Like
Thanks. I’ll put that in and see what happens here. Incidentally, when I run that model with 100mm slices, the outlines it comes up with are way off and bizarre (though it works). 50mm slices crashes it and that’s what I need to do at the moment. I’ll try with your new code (it is such a comfort that there are people like you who really know their way around these quite esoteric areas!).
Thanks again