Hops error

this is the code

import rhinoinside

import ghhops_server as hs

import math

rhinoinside.load()

# System and Rhino can only be loaded after rhinoinside is initialized

import Rhino  

hops = hs.Hops(app=rhinoinside)

@hops.component(

    "/wave",

    name="wave",

    description="create a wave",

    # icon="examples/pointat.png",

    inputs=[

        hs.HopsInteger("X", "x", "number of points in X axis"),

        hs.HopsInteger("Y", "y", "number of points in Y axis"),

        hs.HopsNumber("Height","h","height of waves"),

        hs.HopsNumber("amplitude","a","amplitude of the waves")

    ],

    outputs=[hs.HopsSurface("Wave","w","A mesh made up of a list of points")]

)

def surface(x,y,height,amplitude):

    pts=[]

    for i in range(x):

        for j in range(y):

           

            pt=Rhino.Geometry.Point3d(float(i), float(j), math.sin(i*height) * math.sin(j*height) * amplitude)

            pts.append(pt)

    return Rhino.Geometry.NurbsSurface.CreateFromPoints(pts,int(x),int(y),int(x),int(y))

if __name__ == "__main__":

    hops.start(debug=True)

Have you tried placing a breakpoint in your python script to debug from something like VS Code to make sure a nurbs surface is being created?

Actually, I ran this code in the GhPython component. The surface is created when I use GhPython, but when I use Hops, It does not do anything.

Do you know what’s wrong with that, Steve?

If you return the points only , does the code work?

pts.append(pt)

return pts

This error is thrown: Solution exception:Could not extract keys from dictionary

I wrote some scripts that did not contain for loops, and they worked fine. I guess maybe Hops is not capable of handling for loops

this is what i have written in VScode:


import rhinoinside

import ghhops_server as hs

import math

rhinoinside.load()

# System and Rhino can only be loaded after rhinoinside is initialized

import System

import Rhino  

hops = hs.Hops(app=rhinoinside)

@hops.component(

    "/wave",

    name="wave",

    description="create a wave",

    # icon="examples/pointat.png",

    inputs=[hs.HopsInteger("X", "x", "number of points in X axis")],

    outputs=[hs.HopsInteger("Wave","w","A mesh made up of a list of points")]

)

def surface(x):

    numbers=[]

    for i in range(x):

        numbers.append(i)

    return numbers

if __name__ == "__main__":

    hops.start(debug=True)

and after that, I write the same script in the GhPython component. so as I told you Hops is not capable of handling for loops.
this is what I wrote in the GhPython component:

def surface(x):
    numbers=[]
    for i in range(x):
        numbers.append(i)
    return numbers
a=surface(x)

I am going to attach some images of their outputs. so you can see what’s going on here.


look at the outputs here. as you see the scripts are the same, but the Hops is not working properly.
Is there any solution to that?

Something wrong in your code, loops work fine if you return points only.
But the return surface or points have a problem using rhinoinside
Try this:

from flask import Flask
import ghhops_server as hs
import math
import rhino3dm as rh

app = Flask(__name__)
hops = hs.Hops(app)

@hops.component(

    "/surface",
    name="wave",
    description="create a wave",
    inputs=[
        hs.HopsInteger("X", "x", "number of points in X axis"),
        hs.HopsInteger("Y", "y", "number of points in Y axis"),
        hs.HopsNumber("Height", "h", "height of waves"),
        hs.HopsNumber("amplitude", "a", "amplitude of the waves")
    ],
    outputs=[
        hs.HopsPoint("Points","P","list of points"),
    ]
)

def surface(x,y,height,amplitude):
    pts = []
    for i in range(x):
        for j in range(y):
            pt = rh.Point3d(float(i), float(j), math.sin(i * height) * math.sin(j * height) * amplitude)
            pts.append(pt)
    return pts

if __name__ == "__main__":
    app.run()

image

There are different error messages with Nurbs surface in different cases

import rhinoinside
import ghhops_server as hs
import math
rhinoinside.load()
import System
import Rhino

hops = hs.Hops(app=rhinoinside)

@hops.component(

    "/wave",
    name="wave",
    description="create a wave",
    inputs=[
        hs.HopsInteger("X", "x", "number of points in X axis"),
        hs.HopsInteger("Y", "y", "number of points in Y axis"),
        hs.HopsNumber("Height", "h", "height of waves"),
        hs.HopsNumber("amplitude", "a", "amplitude of the waves")
    ],
    outputs=[
        hs.HopsPoint("Points", "P", "List of points"),
        hs.HopsSurface("Surface", "S", "A surface made up of a list of points")
    ]
)

def wave(x, y, height, amplitude):
    points = System.Collections.Generic.List[Rhino.Geometry.Point3d]()
    pts = []
    for i in range(x):
        for j in range(y):
            pt = Rhino.Geometry.Point3d(float(i), float(j), math.sin(i * height) * math.sin(j * height) * amplitude)
            points.Add(pt)
            pts.append(pt)
    surface = Rhino.Geometry.NurbsSurface.CreateFromPoints(pts, int(x), int(y), int(x), int(y))
    return pts, surface


if __name__ == "__main__":
    hops.start(debug=True)
  • using
points = System.Collections.Generic.List[Rhino.Geometry.Point3d]()
surface = Rhino.Geometry.NurbsSurface.CreateFromPoints(points, int(x), int(y), int(x), int(y))
return points, surface

give this error:

1. Solution exception:Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Rhino.Geometry.Point3d' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.

  • using
pts = []
surface = Rhino.Geometry.NurbsSurface.CreateFromPoints(points, int(x), int(y), int(x), int(y))
return pts, surface

give this error:
1. Solution exception:Unable to read CommonObject from base64 encoded string


  • using
pts = []
surface = Rhino.Geometry.NurbsSurface.CreateFromPoints(pts, int(x), int(y), int(x), int(y))
return pts, surface

give this error:

1. Exception occured in handler:
No method matches given arguments for CreateFromPoints: (<class 'list'>, <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>)
surface = Rhino.Geometry.NurbsSurface.CreateFromPoints(pts, int(x), int(y), int(x), int(y))
1 Like

Yes, I know that this can be done by using the rhino3dm library. Still, I intend to use theRhino.Geometry library as the latter has more functionality. rhinoinside is for having access to the Rhino.geometry library. I want to return a surface using python, not use grasshopper components.
as you said, I think there is something wrong with
import rhinoinside and rhinoinside.load() as they are supposed to let us have access to the Rhino.Geometry library. did you have look at my other example? I used the same script in a for loop but the result were different.

1 Like

You don’t notice that you use:
@hops.component(

"/wave",

And def surface (…) ?
You must use the same name

That did not make any problem for me. But I changed that.

1 Like

there are some example files on McNeel Github that utilized RhinoGeometry and rhinoinside, but there were not a for loop in those scripts. I think for loops make problems when they are used with Rhino.Geometry and rhinoinside.

1 Like

I’m pretty confident that using a for loop is not the problem here. It may be that ghhops_server is not properly handling NurbsSurface return data. Do things work if you call ToBrep() on the surface and return that?

1 Like

Hi Steve please check my post with different error messages. ToBrep give the same error as NurbsSurface

Yes, I tried that. But the problem is still there. Have you tried a for loop or a nested for loop when you use Rhino.Geometry? because in my case, when I use a for loop with other libraries than Rhino.Geometry it works, but whenever I use Rhino.Geometry It does throw errors.

It is not the for loop. This has to do with python determining the correct function to use in RhinoCommon. Below is a working sample.

@hops.component(
    "/wave",
    name="wave",
    description="create a wave",
    inputs=[
        hs.HopsInteger("X", "x", "number of points in X axis"),
        hs.HopsInteger("Y", "y", "number of points in Y axis"),
        hs.HopsNumber("Height", "h", "height of waves"),
        hs.HopsNumber("amplitude", "a", "amplitude of the waves")
    ],
    outputs=[
        hs.HopsSurface("Surface", "S", "A surface made up of a list of points")
    ]
)
def wave(x, y, height, amplitude):
    points = System.Collections.Generic.List[Rhino.Geometry.Point3d]()
    for i in range(x):
        for j in range(y):
            pt = Rhino.Geometry.Point3d(float(i), float(j), math.sin(i * height) * math.sin(j * height) * amplitude)
            points.Add(pt)
    surface = Rhino.Geometry.NurbsSurface.CreateFromPoints(points, x, y, x, y)
    return surface

notice that I am using

points = System.Collections.Generic.List[Rhino.Geometry.Point3d]()

instead of pts=[]. Rhino inside CPython uses pythonnet instead of IronPython that is used in ghpython. Pythonnet is a little stricter on what data types can be passed to functions.

1 Like

Thanks, Steve. It was really constructive. It would be beneficial to add these details to the Hops documentation.

1 Like
def foo(mesh,dist,depth,iter):

    second_mesh=Rhino.Geometry.Mesh()

    vec_normal=System.Collections.Generic.List[Rhino.Geometry.Vector3d]()

    re_pts=System.Collections.Generic.List[Rhino.Geometry.Point3d]()

   

    for i in mesh.vec_normal:

        vec_normal.Add(Rhino.Geometry.Vector3d(i))

    for i in range(len(mesh.Vertices)):

        temp_point=Rhino.Geometry.Point3d.Add(Rhino.Geometry.Point3d(mesh.Vertices[i]),vec_normal[i])

        re_pts.Add(temp_point)

        second_mesh.Vertices.Add(temp_point)

    print(type(mesh.Facevec_normal))

    for i in range(len(mesh.Faces)):

        if mesh.Faces[i].IsQuad:

            ve1 = mesh.Faces[i].A

            ve2 = mesh.Faces[i].B

            pt_1 = re_pts[ve1]

            pt_2 = re_pts[ve2]

            mid_1 = Rhino.Geometry.Point3d.Divide(Rhino.Geometry.Point3d.Add(pt_1,pt_2),2)

            mid_1= Rhino.Geometry.Point3d.Add(mid_1,Rhino.Geometry.Vector3d(mesh.Facevec_normal[i]))

this throws the error:

  1. Exception occured in handler:
    No constructor matches given arguments: (<class ‘Rhino.Geometry.Collections.MeshFaceNormalList’>)
    File “.\app.py”, line 59, in mesh_ex
    mid_5= Rhino.Geometry.Point3d.Add(mid_5,Rhino.Geometry.Vector3d(mesh.FaceNormals))
    but what is wrong here? because I tried itin GHPython and it works perfect but now in HOPS it is throwing an error.
1 Like