Mac OSX AddCircle parameter exception


#1

I can’t get AddCircle to function in python on OSX.
AddCircle wants a plane and a radius as arguments:


and a plane is a four element array of x,y,z arrays for the origin, x axis vector, y axis vector, and z axis vector:

but this code:

throws this exception:

Ideas?


#2

Edit: @harvey looks like you are referencing an old Rhinoscript help file - where did you find that? The current Python rhinoscriptsyntax reference is here - but the link is a bit buried and the online version is not quite as easy to navigate as the normal help file… Maybe we can fix that…

@stevebaer, @Alain Looks like the Python “RhinoScript Fundamentals” rhinoscriptsyntax page is incorrect, it indicates stuff for vb Rhinoscriptsyntax and not Python. And can we get a .chm link on this page as well as this one ?

I would use the PlaneFromPoints method, you only need to have origin, X and Y axes (Z is implied, 3 points determine a plane)

import rhinoscriptsyntax as rs

start_origin=[0.0,5.0,10.0]
start_xaxis=[0.0,-1.0,0.0]
start_yaxis=[0.0,0.0,1.0]
pipe_radius=1.0

start_plane=rs.PlaneFromPoints(start_origin,start_xaxis,start_yaxis)
rs.AddCircle(start_plane, pipe_radius)

HTH, --Mitch


#3

AS the exception explains, You need a 3dPoint not a list.


#4

Sorry Point3d


#5

Well, actually, you can pass a list - as I did in my example above with PlaneFromPoints() - to a lot of rhinoscriptsyntax methods that expect a point3d object - it tries to convert them automatically. The main problem was trying to pass a list of 4 coordinate triples as a “plane” instead of just 3 separate arguments.

The exception got thrown when coerceplane (which is called by AddCircle) failed to convert the 4 triples into a plane object. Then AddCircle(), not having a plane as input, tried to interpret that list as one point3d by using coerce3dpoint… which failed, and then the exception was thrown.

Here’s what AddCircle() is doing “behind the scenes”:

def AddCircle(plane_or_center, radius):
    """Adds a circle curve to the document
    Parameters:
      plane_or_center = plane on which the circle will lie. If a point is
        passed, this will be the center of the circle on the active
        construction plane
      radius = the radius of the circle
    Returns:
      id of the new curve object
    """
    rc = None
    plane = rhutil.coerceplane(plane_or_center, False)
    if plane:
        circle = Rhino.Geometry.Circle(plane, radius)
        rc = scriptcontext.doc.Objects.AddCircle(circle)
    else:
        center = rhutil.coerce3dpoint(plane_or_center, True)
        view = scriptcontext.doc.Views.ActiveView
        plane = view.ActiveViewport.ConstructionPlane()
        plane.Origin = center
        circle = Rhino.Geometry.Circle(plane, radius)
        rc = scriptcontext.doc.Objects.AddCircle(circle)
    if rc==System.Guid.Empty: raise Exception("Unable to add circle to document")
    scriptcontext.doc.Views.Redraw()
    return rc

Here are the coerceplane and coerce3dpoint methods respectively:

def coerceplane(plane, raise_on_bad_input=False):
    "Convert input into a Rhino.Geometry.Plane if possible."
    if type(plane) is Rhino.Geometry.Plane: return plane
    if type(plane) is list or type(plane) is tuple:
        length = len(plane)
        if length==3 and type(plane[0]) is not list:
            rc = Rhino.Geometry.Plane.WorldXY
            rc.Origin = Rhino.Geometry.Point3d(plane[0],plane[1],plane[2])
            return rc
        if length==9 and type(plane[0]) is not list:
            origin = Rhino.Geometry.Point3d(plane[0],plane[1],plane[2])
            xpoint = Rhino.Geometry.Point3d(plane[3],plane[4],plane[5])
            ypoint = Rhino.Geometry.Point3d(plane[6],plane[7],plane[8])
            rc     = Rhino.Geometry.Plane(origin, xpoint, ypoint)
            return rc
        if length==3 and (type(plane[0]) is list or type(plane[0]) is tuple):
            origin = Rhino.Geometry.Point3d(plane[0][0],plane[0][1],plane[0][2])
            xpoint = Rhino.Geometry.Point3d(plane[1][0],plane[1][1],plane[1][2])
            ypoint = Rhino.Geometry.Point3d(plane[2][0],plane[2][1],plane[2][2])
            rc     = Rhino.Geometry.Plane(origin, xpoint, ypoint)
            return rc
    if raise_on_bad_input: raise TypeError("%s can not be converted to a Plane"%plane)
def coerce3dpoint(point, raise_on_error=False):
    "Convert input into a Rhino.Geometry.Point3d if possible."
    if type(point) is Rhino.Geometry.Point3d: return point
    if hasattr(point, "__len__") and len(point)==3 and hasattr(point, "__getitem__"):
        try:
            return Rhino.Geometry.Point3d(float(point[0]), float(point[1]), float(point[2]))
        except:
            if raise_on_error: raise
    if type(point) is Rhino.Geometry.Vector3d or type(point) is Rhino.Geometry.Point3f or type(point) is Rhino.Geometry.Vector3f:
        return Rhino.Geometry.Point3d(point.X, point.Y, point.Z)
    if type(point) is str:
        point = point.split(',')
        return Rhino.Geometry.Point3d( float(point[0]), float(point[1]), float(point[2]) )
    if type(point) is System.Guid:
        rhobj = coercerhinoobject(point, raise_on_error)
        if rhobj:
            geom = rhobj.Geometry
            if isinstance(geom, Rhino.Geometry.Point): return geom.Location
    if raise_on_error: raise ValueError("Could not convert %s to a Point3d" % point)

—Mitch


#6

Passing a list works fine, and thanks to all of you for your help. I’ll file this under “wrong documentation”.

BTW, is there an authoritative list of the subset of python routines available under Mac OSX?

Thanks again.

H


(Steve Baer) #7

What page are you referring to?


#8

Hi Steve,

I sent a mail with details to Alain, I just sent you a copy… He said he would look at it…

Still over on this side of the pond?

Cheers, --Mitch


(Steve Baer) #9

Yep; taking a few days of vacation.


#10

Enjoy! :sunglasses: