Scripting BlendSrf

I need to blend two surfaces but I don’t think there is a Rhinocommon function for this so I am going to script BlendSrf. The first issue I have is that I don’t know how to script the selection of an edge. How can I do this?


1 Like

I don’t believe it is possible to script the BlendSrf command, as it works based on where you pick.

But, I’ve added a new Rhino.Geometry.Brep.CreateBlendSurface static function to the Rhino WIP, if this is of any help.

OK, does this mean it will be available in the next service release? Three other functions I’m hoping to see in rhinocommon are flow, bend, and soft editing of surfaces, not sure if I already mentioned this…


No, but it will be available in the next Rhino WIP release.

Flow and Bend have been in RhinoCommon for a while.


The functionality behind our SoftEditCrv and SoftEditSrf commands is not exposed in Rhino (yet).

Awesome, looking forward to giving those a try.


I’m struggling to get this new command to work, here:

It’s just not giving any output.

I’m also worried in a practical sense that it lacks the edge chaining feature of the Rhino command.

UPDATE: solved, by grabbing the correct interval for the edge curves and nothing showed up since the domain of the intervals were negative numbers up to zero, and I hadn’t used a negative starting domain number so the command had nothing to work with.


try if below example files help. (Rhino6 only). (6.1 KB)
RH6_BlendSrf.3dm (41.7 KB)


I got it to work in the same way, thanks, having Googled curve blend code.

However, I now have no control over the direction of the patch alignment like the native Rhino command affords, nor do I have manual control so far since I don’t know if it’s possible to change the target surface effectively:

Changing the brep edge closed curve seam point doesn’t seems to work.


to reverse the blend direction, you have the True/False toggles for each end.

You would either use _SplitEdge and _MergeEdge so the seam is close to the one of the spherical brep or alternatively untrim the patch first, change the seam point of the trim curve and re-trim. Below is one example using a patch surface similar like yours. (6.6 KB)
RH6_BlendSrf.3dm (123.5 KB)

I guess doing the seam alignment programmatically is more challenging :slight_smile:


SplitEdge indeed introduces a new endpoint viewable with ShowEdges and manually using MergeEdge in Rhino can get rid of the original point, but I only see Split available for brep edges in Rhinocommon, no merge/join command, nor am I sure how I’d control which point got nuked, and frankly I can’t tell how Rhino is choosing which point to keep either with MergeEdge.

There’s also ChangeClosedCurveSeam and SetEndPoint listed under BrepEdge, but they return False when I print them in Python so don’t seem to work.

I do confirm endpoint change using Rhino’s CrvSeam command on a trimming curve used to re-trim an untrimmed surface. I guess Rhinocommon just doesn’t work like it should to change the seam of an existing brep edge?

Simple closest point determination will be my first attempt at automatic alignment of edges for a blend surface.

I’m also confused about how to simply trim a base surface in Rhinocommon, using my modified (end relocated) trimming curve, to acquire a new brep.


Here’s an old post with the same question and no answer except wait for an update to Rhinocommon:

There’s a brep face split command, but it fails to split:

C = Rhino.Collections.CurveList().Add(TrimCurveB)
DEBUG = ChildBreps.Surfaces[0].ToBrep().Faces[0].Split(C, 0.001)


There is unfortunately much more to this than just adding a new curve to the breps curvelist and set it up as a new trim. To do what you want, you would normally create a new empty brep, add the surface to it, then the 2d and 3d curve. Then you setup the outer loop(s), edge(s) and associate the trim(s)… in short, it is easier to get the untrimmed version of the patch surface and it`s trim curve, do the change on the curve (seam) then split the patch surface with it and find out which part to keep.


I found a way that’s simple. You can split a brep face. The rest is bookeeping. This successfully auto-aligns the blend surface just using closest point and rebuilds the target brep by turning its basis surface into a brep then treating it a single brep face. All I’m missing now is flipping the direction of the blend edges so they match, to avoid yet another type of twisted mess.

Rhino 6 WIP Blend Surface Via Rhinocommon (94.2 KB)

import Rhino

BrepFaceA = ParentBrep.Faces[0]
BrepEdgeA = ParentBrep.Edges[2]

BrepFaceB = ChildBreps.Faces[0]
BrepEdgeB = ChildBreps.Edges[0]

TrimCurveB = BrepEdgeB.ToNurbsCurve() # Make curve from child surface border.

HoleStartPoint = BrepEdgeA.PointAt(BrepEdgeA.Domain[0]) # Hole starting point.
ClosestPointParameter = TrimCurveB.ClosestPoint(HoleStartPoint)[1] # Closest point on child surface border to hole start.
TrimCurveB.ChangeClosedCurveSeam(ClosestPointParameter) # Move curve starting point to match hole starting point.
C = Rhino.Collections.CurveList() # Empty Rhino list to properly feed the Split command.
C.Add(TrimCurveB) # Fill list with our single curve.

Rebuild child brep by re-trimming its underlying surface with our starting point modified curve.

AutoAlignedChild = ChildBreps.Surfaces[0].ToBrep().Faces[0].Split(C, 0.001).Faces[1].DuplicateFace(0)
AutoAlignedChildFace = AutoAlignedChild.Faces[0]
AutoAlignedChildEdge = AutoAlignedChild.Edges[0]

BlendBrep = Rhino.Geometry.Brep.CreateBlendSurface(
BrepFaceA, BrepEdgeA, BrepEdgeA.Domain, False, Rhino.Geometry.BlendContinuity.Tangency,
AutoAlignedChildFace, AutoAlignedChildEdge, AutoAlignedChildEdge.Domain, False, Rhino.Geometry.BlendContinuity.Tangency)

BrepEdgeA = BrepEdgeA.ToNurbsCurve()
BrepEdgeB = TrimCurveB


try rs.CurveDirectionsMatch(curve0,curve1). Or in RhinoCommon speaking it should be:

Rhino.Geometry.Curve.DoDirectionsMatch(curve0, curve1)

I guess, if the directions do not match, you would change either rev0 or rev1 variable in:


to False and the other one remains True. Does that help ?


Will try that too, but just the starting point vector angles give me pretty good flipping conditions since I’ve already used closest point to make the endpoints near one another.

However, I have a glitch in that depending on the angle of the little guy and its re-trimming curve, I’m getting not one brep face edge curve but often three, so I get a gap in my blend surface:

There doesn’t seem to be a merge command in Rhinocommon equivalent to Rhino MergeEdge. Maybe I in fact do have to build a brep from scratch, old school?

Rhino 6 WIP Blend Surface Via Rhinocommon (76.6 KB)

Tom Jankowski just released a new plug-in, Advanced Surface Tools, that features his own blend code:

So far it can’t handle this system except by splitting it into quadrants.


i´ve just discovered something funny to move the naked edge vertex in the example patch surface attached below:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

def DoSomething():

    id = rs.coerceguid("310aab71-ebf8-4280-aeca-c3ab1ded98fd")
    if not rs.IsObject(id): return

    pt = rs.GetPoint("Click new naked edge vertex location (on edge)")
    if not pt: return

    brep = rs.coercebrep(id, True)

    rc, param = brep.Curves3D.Item[0].ClosestPoint(pt)
    if not rc: return

    brep.Vertices[0].Location = brep.Curves3D.Item[0].PointAtStart
    scriptcontext.doc.Objects.Replace(id, brep)


It does not create a new naked edge vertex and moves the existing one. Tested with this file only:

PatchSeamTest.3dm (259.1 KB)

btw. if you blend surfaces with different naked edge structure, you might create multiple blends and split opposite edges using SplitEdgeAtParameters method.

EDIT: That would have been too easy i guess. Strike that example above, the changed edge does not seem to survive an edge rebuild and it is not respected by the blend command. I´m still trying to find out why the patch is not selected by _SelBadObjects after changind the edge.


Hi @dale, it would be very helpful to have an overload which allows to pass a list of parameters for each edge to set up some additional blend sections.


Automatic alignment requested too, @dale, like in the Rhino command options, that being the default.

@clement, see the following:

@NikWillmore, I don’t know what “automatic alignment” means. This isn’t a feature of the BlendSrf command. Or am I confused?

1 Like