I appear to have run into a bug in AddRevSurf. Here is how to reproduce: open badRevolveExample.3dm (28.1 KB). Then run the following script, which creates (what should be) the same revolved surface via a macro and via AddRevSrf, and a simple sphere.
Now if you try to eg BooleanSplit the sphere with the surface created via the macro, it works fine. However, if you try the same thing using the surface generated by AddRevSrf, the split fails - the surface appears to have some subtle issue.
Is this a bug or am I missing something?
Thanks a lot,
Egor
import rhinoscriptsyntax as rs
revline=rs.ObjectsByName("_revline")
# create a revolved surface via AddRevSrf
axis=rs.AddLine([0,0,0],[0,0,1])
surf1=rs.AddRevSrf(revline,axis)
rs.ObjectLayer(surf1,rs.AddLayer("AddRevSrf"))
# create another via a macro
rs.Command("SelNone")
rs.SelectObject(revline)
rs.Command("Revolve 0 Enter Enter Enter SelNone SelLast")
rs.UnselectObject(revline)
surf2=rs.SelectedObjects()
surf2=surf2[0]
rs.ObjectLayer(surf2,rs.AddLayer("macro"))
sphere=rs.AddSphere([0,0,0],20)
Interesting. SelDup selects the two revolved surfaces as identical, but Properties>Details says that the surface created by AddRevSrf is a “surface of revolution” and the surface created by the macro is a “rational NURBS surface”. The intersector finds a valid intersection curve in both cases, but the curve fails to split the revolved surface. Pulling the intersection curve to the revolved surface produces a funny result. Hmmm…
Edit - if I convert the surface of revolution to a NURBS surface by moving one control point out a bit and then back the same distance, the split works…
Rhino’s Revolve command creates Nurbs surface due to some difficulty in calculating closest points on surfaces of revolution. The rs.AddRevSrf function should do the same - I’ve reported this as a bug.
This version of rs.AddRevSrf should work better for you.
import math
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext
def AddRevSrfEx(curve_id, axis, start_angle=0.0, end_angle=360.0):
curve = rs.coercecurve(curve_id, -1, True)
axis = rs.coerceline(axis, True)
start_angle = math.radians(start_angle)
end_angle = math.radians(end_angle)
srf = Rhino.Geometry.RevSurface.Create(curve, axis, start_angle, end_angle)
if not srf: return scriptcontext.errorhandler()
ns = srf.ToNurbsSurface()
if not ns: return scriptcontext.errorhandler()
rc = scriptcontext.doc.Objects.AddSurface(ns)
scriptcontext.doc.Views.Redraw()
return rc
@ZmeiGorynych, the problem in your link seems to be fixed already. Do you see this not working on trimmed surfaces ? Below example is identical to the code rs syntax is using:
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext
def OffsetSrf(distance, tolerance=None, both_sides=False, create_solid=False):
brep = rs.coercebrep(id, True)
face = None
if (1 == brep.Faces.Count): face = brep.Faces[0]
if face is None: return scriptcontext.errorhandler()
if tolerance is None: tolerance = scriptcontext.doc.ModelAbsoluteTolerance
newbrep = Rhino.Geometry.Brep.CreateFromOffsetFace(
face, distance, tolerance, both_sides, create_solid)
scriptcontext.doc.Objects.AddBrep(newbrep)
scriptcontext.doc.Views.Redraw()
if __name__=="__main__":
id = rs.GetObject("surface to offset", 8, True, False)
if id:
OffsetSrf(distance=10, both_sides=False, create_solid=True)
is understand now. You`re offsettings a polysurface instead of a surface. Usually this is done using rs.OffsetBrep() but this is not implemented yet in RhinoScript syntax.
thanks! How can I download the WIP? I found this link, but when I click on the big Download button there, I end up here, where I can’t see any link to the WIP.