Open JoshuaWilkes opened 3 years ago
Linked with COMPUTE-148
I believe it is there:
For some reason it isn't showing up in the client libraries. In any case, you should be able to call it with the
computeFetch
method.
(warning: untested pseudocode)
computeFetch('/rhino/geometry/curve/getfilletpoints', ...)
Util.ComputeFetch("/rhino/geometry/curve/getfilletpoints", ...)
ComputeServer.Post<bool>(ComputeServer.ApiAddress(typeof(Curve), null)...
We'll investigate why it isn't showing up in the clients.
Following up on this issue,
I don't seem to get anything other than the webpage response from the api when calling it manually.
<Response [200]> <!DOCTYPE html>
[bool, double t0, double t1, Rhino.Geometry.Plane filletPlane] GetFilletPoints(Rhino.Geometry.Curve curve0, Rhino.Geometry.Curve curve1, double radius, double t0Base, double t1Base)
I haven't figured out yet why GetFilletPoints isn't included in the python client library (we use code generation for the client libraries) but I can confirm that this sample works using the latest version of Rhino Compute from the master
branch.
import compute_rhino3d.Util
import rhino3dm
compute_rhino3d.Util.url = 'http://localhost:8081/'
def curve_fillet_points(curve0, curve1, radius, t0Base, t1Base, multiple=False):
url = "/rhino/geometry/curve/getfilletpoints-curve_curve_double_double_double_double_double_plane"
if multiple: url += "?multiple=true"
args = [curve0, curve1, radius, t0Base, t1Base]
if multiple: args = list(zip(curve0, curve1, radius, t0Base, t1Base))
response = compute_rhino3d.Util.ComputeFetch(url, args)
return response
pt0 = rhino3dm.Point3d(0,0,0)
pt1 = rhino3dm.Point3d(10,0,0)
pt2 = rhino3dm.Point3d(0,10,0)
l1 = rhino3dm.LineCurve(pt0, pt1)
l2 = rhino3dm.LineCurve(pt0, pt2)
rv = curve_fillet_points(l1, l2, 1.5, 0, 0)
print(rv)
# [True, 1.4999999999999998, 1.4999999999999998, {'Origin': {'X': 1.5, 'Y': 1.5, 'Z': 0.0}, 'XAxis': {'X': 0.0, 'Y': -1.0, 'Z': 0.0}, 'YAxis': {'X': -1.0, 'Y': 0.0, 'Z': 0.0}, 'ZAxis': {'X': 0.0, 'Y': 0.0, 'Z': -1.0}, 'Normal': {'X': 0.0, 'Y': 0.0, 'Z': -1.0}}]
I am unable to duplicate your experience @pearswj . We have updated to commit 49dba9f: "rhino":"7.2.21012.11001","compute":"1.0.0.607","git_sha":"49dba9fb"}
I've copy/pasted your code above:
import compute_rhino3d.Util
import rhino3dm
import os
if os.environ.get('userdomain') == "XXX":
internal_proxy_address = "http://ZZZZ"
os.environ["HTTP_PROXY"] = f"{internal_proxy_address}:999999"
os.environ["HTTPS_PROXY"] = f"{internal_proxy_address}:999999"
compute_rhino3d.Util.apiKey = "ABCD"
compute_rhino3d.Util.url = "https://YYYY"
def curve_fillet_points(curve0, curve1, radius, t0Base, t1Base, multiple=False):
url = "/rhino/geometry/curve/getfilletpoints-curve_curve_double_double_double_double_double_plane"
if multiple: url += "?multiple=true"
args = [curve0, curve1, radius, t0Base, t1Base]
if multiple: args = list(zip(curve0, curve1, radius, t0Base, t1Base))
response = compute_rhino3d.Util.ComputeFetch(url, args)
return response
pt0 = rhino3dm.Point3d(0,0,0)
pt1 = rhino3dm.Point3d(10,0,0)
pt2 = rhino3dm.Point3d(0,10,0)
l1 = rhino3dm.LineCurve(pt0, pt1)
l2 = rhino3dm.LineCurve(pt0, pt2)
rv = curve_fillet_points(l1, l2, 1.5, 0, 0)
print(rv)
I get the following result:
File "C:\Program Files\Python37\lib\json\__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "C:\Program Files\Python37\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Program Files\Python37\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
What happens if you temporarily replace return r.json()
at the end of computeFetch()
(compute_rhino3d/Util.py) with return r.text
? That will allow us to see what text the json parser is failing to parse.
I had to use str(r)
(r is a requests.mode.Response but r.text()
gives "TypeError: 'str' object is not callable").
From print(str(r))
I get: "<Response [200]>"
r.text
returns the body as a string – that's why it complains if you call it as a method with ()
. Good to know it's returning 200 though!
We need to add some request error handling to the client library, but for now this should get us some useful information.
I read a set of parentheses that you hadn't written...
r.text is:
<!DOCTYPE html><html><body><H1>GetFilletPoints</H1>
<p>
[bool, double t0, double t1, Rhino.Geometry.Plane filletPlane] GetFilletPoints(Rhino.Geometry.Curve curve0, Rhino.Geometry.Curve curve1, double radius, double t0Base, double t1Base)<br>
</p></body></html>
@pearswj bumping...
Very strange. The response is the same as if you called GET /rhino/geometry/curve/getfilletpoints-curve_curve_double_double_double_double_double_plane
, but the ComputeFetch()
function should be using POST
. Are you able to call other functions, such as compute_rhino3d.Curve.GetLength()
? Can you test it without the proxy?
Removing the proxy doesn't change the behaviour (we run from both our company network, where the proxy is necessary, and from AWS instances where it isn't. Currently we're working from home due to covid lockdown, so the proxy isn't needed):
import compute_rhino3d.Util
import rhino3dm
import os
compute_rhino3d.Util.apiKey = ""
compute_rhino3d.Util.url = ""
def curve_fillet_points(curve0, curve1, radius, t0Base, t1Base, multiple=False):
url = "/rhino/geometry/curve/getfilletpoints-curve_curve_double_double_double_double_double_plane"
if multiple: url += "?multiple=true"
args = [curve0, curve1, radius, t0Base, t1Base]
if multiple: args = list(zip(curve0, curve1, radius, t0Base, t1Base))
response = compute_rhino3d.Util.ComputeFetch(url, args)
return response
pt0 = rhino3dm.Point3d(0,0,0)
pt1 = rhino3dm.Point3d(10,0,0)
pt2 = rhino3dm.Point3d(0,10,0)
l1 = rhino3dm.LineCurve(pt0, pt1)
l2 = rhino3dm.LineCurve(pt0, pt2)
rv = curve_fillet_points(l1, l2, 1.5, 0, 0)
print(rv)
Ouput (with Util.ComputeFetch() still returning r.text):
<!DOCTYPE html><html><body><H1>GetFilletPoints</H1>
<p>
[bool, double t0, double t1, Rhino.Geometry.Plane filletPlane] GetFilletPoints(Rhino.Geometry.Curve curve0, Rhino.Geometry.Curve curve1, double radius, double t0Base, double t1Base)<br>
</p></body></html>
compute_rhino3d.Curve.GetLength() doesn't work (I actually ran into this problem with GetLength() a long time ago but had forgotten, because I got around it by using Curve.GetLength1() which works just fine).
import compute_rhino3d.Util
import compute_rhino3d.Curve
import rhino3dm
import os
compute_rhino3d.Util.apiKey = ""
compute_rhino3d.Util.url = ""
pt0 = rhino3dm.Point3d(0,0,0)
pt1 = rhino3dm.Point3d(10,0,0)
l1 = rhino3dm.LineCurve(pt0, pt1)
rv = compute_rhino3d.Curve.GetLength( l1 )
print(rv)
Outputs:
{"statusCode":404,"message":"The resource you have requested cannot be found.","details":""}
If I use GetLength1():
import compute_rhino3d.Util
import compute_rhino3d.Curve
import rhino3dm
import os
compute_rhino3d.Util.apiKey = ""
compute_rhino3d.Util.url = ""
pt0 = rhino3dm.Point3d(0,0,0)
pt1 = rhino3dm.Point3d(10,0,0)
l1 = rhino3dm.LineCurve(pt0, pt1)
#rv = compute_rhino3d.Curve.GetLength( l1 )
rv = compute_rhino3d.Curve.GetLength1( l1, 1 )
print(rv)
it outputs:
10.0
@FergusH I'm perplexed. I've tested the script as you wrote it against several instances of Compute on different machines and I can't reproduce this behaviour. Can you try calling our test server to see if you get the same result as I do?
# mcneel test server connection settings
compute_rhino3d.Util.url = "https://compute.rhino3d.com/"
compute_rhino3d.Util.authToken = "" # token from http://rhino3d.com/compute/login
p.s. The GetLength()
was fixed recently (#147). Try build 1.0.0.619 or newer.
I've just tried your server @pearswj , I still get the same results.
I've tried from my local machine; in fresh venvs; from vms in the cloud - all the same. I've had colleagues here try it, they get the same result as me. JoshuaWilkes who started this thread is from an external contractor that is doing work for us, he gets the same.
I can't think of any other commonality between everything I've tried at this end....
I appreciate you being thorough. Here's a functionally equivalent python 3 script that doesn't use any modules, except the built-in urllib
. Could you test this against our compute.rhino3d.com server? It might be worth trying this script (and the previous script, if successful) against an instance of Compute running on your local machine too. It should be clear in the logs whether Compute is receiving a GET
or a POST
request.
import urllib.request
baseurl = 'https://compute.rhino3d.com'
token = '' # token from https://rhino3d.com/compute/login
headers = { 'Authorization': 'Bearer ' + token }
# baseurl = 'https://my.server.com'
# headers = { 'RhinoComputeKey': 'API_KEY' }
# baseurl = 'http://localhost:8081'
url = baseurl + '/rhino/geometry/curve/getfilletpoints-curve_curve_double_double_double_double_double_plane'
data = b'[{"version": 10000, "archive3dm": 60, "opennurbs": -1912572244, "data": "+n8CAIEAAAAAAAAA+/8CABQAAAAAAAAA29TXTkfp0xG/5QAQgwEi8PSb6SP8/wIASQAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkQAMAAAAexxcp/38CgAAAAAAAAAAA"}, {"version": 10000, "archive3dm": 60, "opennurbs": -1912572244, "data": "+n8CAIEAAAAAAAAA+/8CABQAAAAAAAAA29TXTkfp0xG/5QAQgwEi8PSb6SP8/wIASQAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkQAMAAACIZNn3/38CgAAAAAAAAAAA"}, 1.5, 0, 0]'
req = urllib.request.Request(url, data, headers, method='POST')
with urllib.request.urlopen(req) as f:
print(f.getcode())
print(f.read())
# 200
# b'[true,1.4999999999999998,1.4999999999999998,{"Origin":{"X":1.5,"Y":1.5,"Z":0.0},"XAxis":{"X":0.0,"Y":-1.0,"Z":0.0},"YAxis":{"X":-1.0,"Y":0.0,"Z":0.0},"ZAxis":{"X":0.0,"Y":0.0,"Z":-1.0},"Normal":{"X":0.0,"Y":0.0,"Z":-1.0}}]'
Thanks very much @pearswj for your patience and responses throughout this - the new code works correctly with your server, but not with ours.
I can't explain why I was getting unexpected responses from your server earlier, but in any case it's now obvious that our server has a problem. As luck would have it it's being rebuilt tomorrow anyway, I'll ask for this to be investigated/checked during.
@pearswj it was the trailing slash, e.g.: compute_rhino3d.Util.url = "https://compute.rhino3d.com/"
Your web server apparently strips it away if it's present, ours doesn't - removing the trailing slash in our url has fixed the problem...
Glad you figured it out and thanks for letting me know. I've opened #218 to make sure that the client constructs well-formed urls without missing or double slashes. I'll leave this open to track getting GetFilletPoints
added to the client.
https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Curve_GetFilletPoints.htm
Currently implementing a script that requires this function from RhinoCommon which is not currently available via rhino_compute.
Can this functionality be implemented?
Thanks