How to use Handlebar Editor (HBar) from Python

Hello,

We’ve been successful in moving the control points of a surface using Python - but we were discussing how helpful it would be to pick any point on a surface and make adjustments directly (not just where a CP is). Along comes the handlebar editor command under the Edit > Control Points menu! It does exactly what we want to do, but I have not found anything in the documentation about how to do this from a script.

Is there a way to accomplish something similar via Python?

Thanks for your help.

1 Like

Hi @Henry_Wede,

The HBar command is not scriptable, unfortunately.

It might be possible to write a Python version. It would require a custom display conduit and some special point picking to choose and move a custom drawn grip.

– Dale

1 Like

Thanks Dale -

Is there a way to accomplish the same thing - moving a point on a surface - without the HBar command specifically? I tried to add a knot, make the move, then remove the knot but that didn’t work out. The HBar command draws UV lines through the selected point so I thought that I was being clever. Not so much.

Is the HBar command doing some things and then using RhinoCommon to move the related control points?

Henry

1 Like

Hi @Henry_Wede,

If you want to go the grip route, here are a few samples you might want to look at:

test_move_grips.py (803 Bytes)
test_move_grips.py (2.4 KB)

For NURBS surface, you can always get/set control points.

https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.collections.nurbssurfacepointlist

– Dale

1 Like

I will take a look at the links that you provided - I’m going to be on another project for a couple days.
We have been able to move the control points using the grips.

But being able to move specific points (as the HBar command does) would make the code much easier and allow us a lot more control.

Thanks for getting back to me.

1 Like

Hello,
I am trying the direction of the Rhino.Geometry.Collections.NurbsSurfacePointList as you suggested. I’m not sure how it will work just yet because I am getting hung up on something that is a little frustrating - creating the Geometry object in order to access the collection. Here is what I have tried

SurfaceId = rs.GetObject("Pick a surface", rs.filter.surface)
SurfaceObject = rs.coercegeometry(SurfaceId)
print( type(SurfaceObject) ) 
RhinoSurface = rg.NurbsSurface(SurfaceObject)
SomePoint = RhinoSurface.NurbsSurfacePointList.GetControlPoint(0.5, 0.5)

Which does NOT work, but brings up two questions.

First, when I look at the Properties → Details of the surface that I clicked on it returns this:
surface

ID: 34b80a75-50e0-4e61-90b4-9110d94cf337 (15781)
Object name: shell_1
Layer name: Temporary
Render Material:
source = from layer
index = -1

Geometry:
Valid surface.
trimmed surface.
NURBS Surface"U": degree =3 CV count = 4 (0 <= U <= 4.84834)
“V”: degree =3 CV count = 5 (0 <= V <= 3.6792)
Edge Tally:
4 boundary edges
Edge Tolerances: 0 to 0.001
median = 0.001 average = 0.00075
Vertex Tolerances: all smaller than 0.000001
Render mesh: 1 mesh 93 vertices 94 polygons
Created with quality meshing parameters.
Analysis mesh: 1 mesh 93 vertices 94 polygons
Created with default analysis meshing parameters.

And this indicates a NURBS surface, but the value from rs.coercegeometry(SurfaceId) is a <type ‘Brep’> which the rg.NurbsSurface(SurfaceObject) doesn’t accept. And that is the current road block that I need to get past.

Second, this seems like I will be able to to move the surface at an arbitrary point like the HBar editor. Somehow I will choose a point, get the UV values at that location, get a “control point” at that location, move it normal to the surface, and that is it. Sorry if I am mixing “grip” and “control point”. Does this plan sound tragically flawed? There is code that will choose the points and the transformation so the user interface is zero.

Thank you for your help,
Henry

1 Like

Hi @Henry_Wede, try below to get a NurbsSurface from the brep. (A brep consists of brep faces and each brep face has an underlying surface which can be converted to a nurbs surface:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

def DoSomething():
    
    srf_id = rs.GetObject("Select surface", rs.filter.surface, True, False)
    if not srf_id: return
    
    brep = rs.coercegeometry(srf_id)
    if brep.Faces.Count != 1: return

    surface = brep.Faces[0].ToNurbsSurface()
    control_pt = surface.Points.GetControlPoint(0, 0)
    
    scriptcontext.doc.Objects.AddPoint(control_pt.Location)
    scriptcontext.doc.Views.Redraw()

DoSomething()

Note two things, you cannot do something like this in your example:

SomePoint = RhinoSurface.NurbsSurfacePointList.GetControlPoint(0.5, 0.5)

To access the NurbsSurfacePointList you might use surface.Points instead. To access control points using surface.Points.GetControlPoint you need to pass integers (not floats) as these numbers are the indices of the points along uv directions.

No, it should be possible. Below is an example which does it and moves the first control point (u=0 and v=0) along the normal by 5.0 units:

def DoSomething():
    
    srf_id = rs.GetObject("Select surface", rs.filter.surface, True, False)
    if not srf_id: return
    
    brep = rs.coercegeometry(srf_id)
    if brep.Faces.Count != 1: return

    surface = brep.Faces[0].ToNurbsSurface()
    control_pt = surface.Points.GetControlPoint(0, 0)
    
    rc, u, v, n = surface.Points.UVNDirectionsAt(0, 0)
    xform = Rhino.Geometry.Transform.Translation(n * 5.0)
    new_pt = Rhino.Geometry.Point3d(control_pt.Location)
    new_pt.Transform(xform)
    surface.Points.SetPoint(0, 0, new_pt)
    
    scriptcontext.doc.Objects.AddSurface(surface)
    scriptcontext.doc.Views.Redraw()

DoSomething()

does this help a bit ? btw. you might as well check out Surface.CreateSoftEditSurface method…
_
c.

1 Like

As always, thank you for an information filled answer.

I overlooked the integer parameters for the GetControlPoint method. I was hoping that non-integer values would let me choose an arbitrary point like the HBar editor. I have looped back to the control points once again :slight_smile:

However, your suggestion about the soft edit might be the clue that I was looking for. I just did a quick comparison (manually, no scripting) between the HBar editor and the soft edit command and they seem fairly similar. HBar seems a little more agressive but that could just my manual test.

I think that I am going to spend some time trying the CreateSoftEditSurface method and see what kind of a mess I can make.

Thanks again for your time.

2 Likes

I’m researching this, but mostly from maybe a GH or entirely manual standpoint, because this has been on my mind since I stumbled on it again recently, and further realized the possibilities.

I’m surprised to see this functionality of Rhino so hush hush. :face_holding_back_tears:

Is it GH’able I wonder. :slightly_smiling_face:

I’m looking for more signs of how awesome Hbar is, but not seeing very many cool pictures and videos.

Guess I’ll search youtube or something.