Giter Club home page Giter Club logo

compute.rhino3d's Introduction

compute.rhino3d's People

Contributors

andresjacobo avatar andyopayne avatar archidog1998 avatar cwensley avatar dan-rigdon-bel avatar dependabot[bot] avatar eirannejad avatar enmerk4r avatar fraguada avatar fstwn avatar golsby avatar jesterking avatar mans-ttcore avatar pearswj avatar sbaer avatar scotttd avatar thetonyho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

compute.rhino3d's Issues

Compute doesn't load newly registered plug-ins

Rhino plug-ins that have been registered by writing keys under HKEY_LOCAL_MACHINE\Software\McNeel\Rhinoceros\7.0\Plug-ins aren't loaded when Rhino is started in headless mode by Compute.

Using Karamba3d to test...

  1. Delete HKEY_CURRENT_USER\Software\McNeel\Rhinoceros\7.0\Plug-Ins\06bb1e79-5456-47a1-ad6d-111118cd894b
  2. Start compute.geometry.exe
  3. Solve karamba_compute.gh (unzip first)
  4. The output will be empty and Compute will log System.Exception: GH - Missing Definition Objects
  5. Stop compute.geometry.exe
  6. Run Rhino normally and then close it; you may see a "Preparing plug-ins for first use" dialog pop up โ€“ that's the Karamba plug-in being loaded
  7. Restart compute.geometry.exe again and solve karamba_compute.gh again
  8. This time the output won't be empty!

inconsistant results when running multiple samualtaneous requests with single grasshopper script (that takes awhile to solve)

summary

when compute server is hit with 2 requests for the same grasshopper script, it seems to run both of them samualtaneously (instead of creating a que), which results in errors, inconsistent results, or request failure (sometimes a combination of these).

example test file

the following grasshopper script and python code was created to illiustrate this issue

grasshopper script

gh_script1

The grasshopper script is very simple, it takes two numbers, squres them, and in the first case it returns it immediately, and in the second case it returns after waiting 3 sec [note1].

python code

the following python script [note2] simply makes 2 API calls a compute API with inputs 2 and 3 for the grasshopper script discribed above
Once Each API call returns, it will print out the returned result
An async API call is used here to simulate two users sending requests at the same time

result

expected print (maybe 1/10 times it does return correctly)

making FIRST call... with inputs: 
[{'ParamName': 'RH_IN:in_inst', 'InnerTree': {'0': [{'data': 2}]}}, {'ParamName': 'RH_IN:in_wait', 'InnerTree': {'0': [{'data': 2}]}}]
making SECOND call... with inputs: 
[{'ParamName': 'RH_IN:in_inst', 'InnerTree': {'0': [{'data': 3}]}}, {'ParamName': 'RH_IN:in_wait', 'InnerTree': {'0': [{'data': 3}]}}]

output for FIRST call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '4.0'}]}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '4.0'}]}}]

output for SECOND call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '9.0'}]}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '9.0'}]}}]

actural printed result example 1

output for SECOND call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '4.0'}]}}]

output for FIRST call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '4.0'}]}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '4.0'}]}}]

actural printed result example 2

output for SECOND call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {}}]

output for FIRST call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '4.0'}]}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {}}]

actural printed result example 3

output for FIRST call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {}}]

output for SECOND call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {}}]

actural printed result example 4

output for SECOND call: 

output for FIRST call: 
[{'ParamName': 'RH_OUT:out_wait', 'InnerTree': {'{ 0; }': [{'type': 'System.Double', 'data': '4.0'}]}}, {'ParamName': 'RH_OUT:out_inst', 'InnerTree': {}}]
Traceback (most recent call last):
  File "C:/Users/kpflaptop/cloud_based_tools/resthopper/calling compute at the same time/SimultaneousCalls.py", line 73, in <module>
    loop.run_until_complete(future2)
  File "C:\Users\kpflaptop\anaconda3\envs\compute_rhino_test\lib\asyncio\base_events.py", line 616, in run_until_complete
    return future.result()
  File "C:/Users/kpflaptop/cloud_based_tools/resthopper/calling compute at the same time/SimultaneousCalls.py", line 44, in print_async_evaluate_definition
    print(output['values'])
KeyError: 'values'

error on server:

17:40:05 ERR] Error in grasshopper component: "Num" (ab3ad373-558d-4408-990d-db711d20c6e7): Cyclical data stream detected, parameter Num is recursive.
[17:40:05 ERR] Error in grasshopper component: "Num" (ab3ad373-558d-4408-990d-db711d20c6e7): Object reference not set to an instance of an object.
[17:40:05 ERR] Error in grasshopper component: "Wait 3 sec" (7af0522f-ddaa-4f07-b16d-f8975fcd5254): Object reference not set to an instance of an object.

notes

note 1: the code inside the "wait 3 sec" component is:

import time
time.sleep(3)
a = x

note2: python code that was run

import asyncio
import aiofiles
import aiohttp
import compute_rhino3d.Util
import compute_rhino3d.Curve
import json
from ghload import *

compute_rhino3d.Util.url = "..."
compute_rhino3d.Util.authToken = "..."
grasshopper_link = "https://rhino.kpfui.dev/api/definition/SimultaneousCalls.gh"
grasshopper_path = "SimultaneousCalls.gh"


async def async_evaluate_definition(definition, trees):
    args = {'algo': None, 'pointer': definition, 'values': [tree.data for tree in trees]}

    class __Rhino3dmEncoder(json.JSONEncoder):
        def default(self, o):
            if hasattr(o, "Encode"):
                return o.Encode()
            return json.JSONEncoder.default(self, o)

    auth_token = compute_rhino3d.Util.authToken
    url = "http://3.236.150.240:80/grasshopper"
    postdata = json.dumps(args, cls=__Rhino3dmEncoder)
    headers = {
        'Authorization': 'Bearer ' + auth_token,
        'User-Agent': 'compute.rhino3d.py/' + compute_rhino3d.Util.__version__,
        'RhinoComputeKey': 'F$YWdl07jYi*GF&g9EEMhn0R&4*$6def^nE'
    }
    async with aiohttp.ClientSession() as session:
        async with session.post(url, headers=headers, data=postdata) as resp:
            data = await resp.json()
    return data


async def print_async_evaluate_definition(ghf, trees, name):
    print("making " + name + " call... with inputs: ")
    print([tree.data for tree in trees])
    output = await async_evaluate_definition(ghf, trees)
    print("")
    print("output for " + name + " call: ")
    print(output['values'])

# grasshopper file input and output names
input_list = [
    "in_inst",
    "in_wait"
]
output_list = [
    "out_inst",
    "out_wait"
]

# set numerical inputs
inst1 = 2
wait1 = 2

inst2 = 3
wait2 = 3

# create list of input trees for two api calls
trees1 = [create_tree(input_list[0], inst1), create_tree(input_list[1], wait1)]
trees2 = [create_tree(input_list[0], inst2), create_tree(input_list[1], wait2)]

# api call
print("---------------------------test begin--------------------------")
loop = asyncio.get_event_loop()
future1 = asyncio.ensure_future(print_async_evaluate_definition(grasshopper_link, trees1, "FIRST"))
future2 = asyncio.ensure_future(print_async_evaluate_definition(grasshopper_link, trees2, "SECOND"))
loop.run_until_complete(future1)
loop.run_until_complete(future2)

# output2 = gh.EvaluateDefinition(grasshopper_link, trees2)['values']
# print("output for SECOND call!!!: ")
# print("inst out = " + output2[0]['InnerTree']['{ 0; }'][0]['data'])
# print("wait out = " + output2[1]['InnerTree']['{ 0; }'][0]['data'])

print("---------------------------test end--------------------------")

Update to .NET 4.8

Rhino 7 now requires .NET 4.8. We might as well update this project to target 4.8 as well

Publish Hops to Yak

Publish Hops to Yak for distribution. The package should include the hops.gha as well as a subdirectory containing the compute assemblies.

Support animate for caching purposes

Animating a slider in grasshopper is currently done for generating images. It could also be used for calling compute a bunch of times and filling up a cache. Our AppServer already supports caching and with a multiple compute backend architecture in place we could get see a nice boost in perceived performance.

Currently animating a slider will solve this issue, but it would be nice to provide an option to animate and not produce images. Maybe we could do something simple in Grasshopper's animation controls dialog

Request for Info: usage with cURL

This is a really exciting project!

I have a backend in Go that i would like to use controller to interface with the compute service. I'd like to stick with go but it's not truly a dealbreaker for me. To map out the functionality i'd need to write in Go i like to ping endpoints with cURL. I'm curious to learn how i can chain operations together with individual rest operations agains the compute service.

This is a simplistic example but would go a long way in helping me understand some of the server mechanics for use with cURL:

  • invoke a scene
  • create a circle in scene
  • extrude circle by "n" along z-axis

i did see the expansive list of endpoints exposed by the api but i'm still a bit fuzzy on the operations required to chain things together, from call to call.

again my end goal is to write a client to the compute api in Go with the intention of open sourcing it as a standalone package, but wanted to get a lay of the land with cURL.

additionally are there any resources for the compute.frontend service? i didn't seem to be able to find any

thanks again, this is a super super super exciting project.

-J

Flag to skip loading GH on start

There are cases where Grasshopper is not needed on a compute server. We can improve the start up time for compute by skipping the forced loading of grasshopper when compute starts.

Add a flag/environment variable to tell compute to skip manual loading of grasshopper at start

Resthopper crashes when a grasshopper definition has RH_IN or RH_OUT group without associated object,

Sometimes, not sure how or why, Grasshopper fails to handle the deletion of groups correctly and ends up keeping the group without any objects inside. These groups are not visible, and can only be found using search. And when you try to locate them they are located top left of the canvas. This is probably a bug that should be corrected in Grasshopper.

Screenshot 2020-06-15 at 17 46 49

When a group is this kind is sent to Rhino Compute, and marked as RH_IN or RH_OUT it is assumed that the group is not empty, and crashes if it is.
https://github.com/mcneel/compute.rhino3d/blob/master/src/compute.geometry/ResthopperEndpoints.cs#L115
https://github.com/mcneel/compute.rhino3d/blob/master/src/compute.geometry/ResthopperEndpoints.cs#L483

Since it is really hard to delete the invisible group (only way I found is manually editing the ghx file) I suggest groups without objects are checked and ignored.

I will attach example of problematic gh file as soon as I have a clean one.

Consider registering media type (mime type) for 3dm files/blobs

Based on a question from ShapeDiver on the forum...

http://tools.ietf.org/html/rfc2045#section-5

The purpose of the Content-Type field is to describe the data
contained in the body fully enough that the receiving user agent can
pick an appropriate agent or mechanism to present the data to the
user, or otherwise deal with the data in an appropriate manner. The
value in this field is called a media type.

HISTORICAL NOTE: The Content-Type header field was first defined in
RFC 1049. RFC 1049 used a simpler and less powerful syntax, but one
that is largely compatible with the mechanism given here.

The Content-Type header field specifies the nature of the data in the
body of an entity by giving media type and subtype identifiers, and
by providing auxiliary information that may be required for certain
media types. After the media type and subtype names, the remainder
of the header field is simply a set of parameters, specified in an
attribute=value notation. The ordering of parameters is not
significant.

I suggest either model/3dm or model/vnd.3dm based on a quick review of the information. My understanding is that the vnd prefix is suitable for commercial/proprietary types. The 3dm file format is proprietary, but the tools for reading and writing it are open source. I've used model/vnd.3dm in the examples below.

A couple of examples, based on my understanding of why this is useful...

  1. The client calls the server's /export endpoint with the Accept header set to model/vnd.3dm. The server responds by exporting a saved model as a 3dm file and returning the binary data in the response body. The server could also support model/stl and model/obj.
  2. The client calls the server's /convert endpoint with a Content-Type: model/stl and Accept: model/vnd.3dm and the contents of a binary STL file in the request body. The server returns a 3dm file in the response body that contains a mesh that was created from the STL file.

I'm unsure if there should be special considerations for sending and receiving 3dm blobs (i.e. the serialised opennurbs geometry data that compute deals with). Perhaps for this we should use model/vnd.3dm+json, as per RFC 3023.

We may need to register something, at some point. For now I'm just taking notes!

References

Examples

Defaults for Inputs

If a contextual has inputs set in a remote definition, we could use these as defaults for inputs on the Hops component.

Remote solve by component name/id

I'm still not sure how useful this is, but jotting down the idea here for safe keeping. We could give Hops the name/id of an existing component and have that component solved on multiple external compute instances. If there was a component that takes a long time to solve a large set of input, this may prove useful.

The other potential use case is to allow for some online version of GH that solved components using compute.

Investigate DWG export

It should be possible to use RhinoCommon on Compute (via a C# script component in a Grasshopper definition, for example) to export a 3dm to DWG (see COMPUTE-116).

Exception raised on `/rhino/geometry/areamassproperties/compute-brep_bool_bool_bool_bool ` compute server

Hi,

We ran into this exception when using the compute server which was self hosted. Any ideas what might be causing it?

This is a script that will cause the issue.

import rhino3dm
import compute_rhino3d.Util
import compute_rhino3d.AreaMassProperties

compute_rhino3d.Util.apiKey = "1234"
compute_rhino3d.Util.url = "http://ip.com"
start = rhino3dm.Point3d(250, 250, 0)
end = rhino3dm.Point3d(0, 0, 0)
crv = rhino3dm.Curve.CreateControlPointCurve([start,end],1)
extru = rhino3dm.Extrusion.Create( crv, 500, False)
massProps = compute_rhino3d.AreaMassProperties.Compute6( extru, True, False, False, False )

Running this script causes the compute server to crash with this exception

[2020-10-16T02:54:55.5242837+00:00] "POST /rhino/geometry/areamassproperties/compute-brep_bool_bool_bool_bool HTTP/1.1" 200 -

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at UnsafeNativeMethods.ON_Brep_SetTolerancesBoxesAndFlags(IntPtr pBrep, Boolean bLazy, Boolean bSetVertexTolerances, Boolean bSetEdgeTolerances, Boolean bSetTrimTolerances, Boolean bSetTrimIsoFlags, Boolean bSetTrimTypeFlags, Boolean bSetLoopTypeFlags, Boolean bSetTrimBoxes)
   at Rhino.Geometry.Brep..ctor(SerializationInfo info, StreamingContext context)
   at Void .ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)(Object[] )
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
   at compute.geometry.GeometryEndPoint.HandlePostHelper(JArray ja, Dictionary`2 returnModifiers) in C:\projects\compute-rhino3d\src\compute.geometry\GeometryEndPoint.cs:line 472
   at compute.geometry.GeometryEndPoint.Post(NancyContext context) in C:\projects\compute-rhino3d\src\compute.geometry\GeometryEndPoint.cs:line 385
   at compute.geometry.RhinoPostModule.<>c__DisplayClass0_0.<.ctor>b__0(Object _) in C:\projects\compute-rhino3d\src\compute.geometry\Program.cs:line 163
   at Nancy.Routing.Route.<>c__DisplayClass4.<Wrap>b__3(Object parameters, CancellationToken context)
   at Nancy.Routing.Route.Invoke(DynamicDictionary parameters, CancellationToken cancellationToken)
   at Nancy.Routing.DefaultRouteInvoker.Invoke(Route route, CancellationToken cancellationToken, DynamicDictionary parameters, NancyContext context)
   at Nancy.Routing.DefaultRequestDispatcher.<>c__DisplayClass2.<Dispatch>b__0(Task`1 completedTask)
   at Nancy.Routing.DefaultRequestDispatcher.Dispatch(NancyContext context, CancellationToken cancellationToken)
   at Nancy.NancyEngine.<>c__DisplayClasse.<InvokeRequestLifeCycle>b__c(Task`1 t)
   at Nancy.NancyEngine.InvokeRequestLifeCycle(NancyContext context, CancellationToken cancellationToken, IPipelines pipelines)
   at Nancy.NancyEngine.HandleRequest(Request request, Func`2 preRequest, CancellationToken cancellationToken)
   at Nancy.NancyEngineExtensions.HandleRequest(INancyEngine nancyEngine, Request request, Func`2 preRequest, Action`1 onComplete, Action`1 onError, CancellationToken cancellationToken)
   at Nancy.Owin.NancyMiddleware.<>c__DisplayClass4.<>c__DisplayClass6.<UseNancy>b__1(IDictionary`2 environment)
   at compute.geometry.LoggingMiddleware.<Invoke>d__1.MoveNext() in C:\projects\compute-rhino3d\src\compute.geometry\Startup.cs:line 33
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
   at compute.geometry.LoggingMiddleware.Invoke(IOwinContext ctx)
   at Microsoft.Owin.Cors.CorsMiddleware.<Invoke>d__4.MoveNext()
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.Owin.Cors.CorsMiddleware.Invoke(IDictionary`2 environment)
   at Microsoft.Owin.Hosting.Utilities.Encapsulate.Invoke(IDictionary`2 environment)
   at Microsoft.Owin.Host.HttpListener.OwinHttpListener.<ProcessRequestAsync>d__30.MoveNext()
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.Owin.Host.HttpListener.OwinHttpListener.ProcessRequestAsync(HttpListenerContext context)
   at Microsoft.Owin.Host.HttpListener.OwinHttpListener.<ProcessRequestsAsync>d__29.MoveNext()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
   at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action action, Boolean allowInlining, Task& currentTask)
   at System.Threading.Tasks.Task.FinishContinuations()
   at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
   at System.Threading.Tasks.TaskFactory`1.<>c__DisplayClass35_0.<FromAsyncImpl>b__0(IAsyncResult iar)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
   at System.Net.ListenerAsyncResult.IOCompleted(ListenerAsyncResult asyncResult, UInt32 errorCode, UInt32 numBytes)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

Use Prompt from Input Contextuals

Contextual components (Get Integer, Get String, Get Number, Get Geometry) have a prompt setting. When the prompt is set, use this to add a description to the input for a Hops component

Running server on Windows 10

Is it possible to run it on Windows 10 for development purposes? It fails with err: frontend Url not reserved. Running netsh http add urlacl url="http://+:80/" user="Everyone" in administrator console gives this:

Create SDDL failed, Error: 1332
 The parameter is incorrect.

Grasshopper scripts with PolylineCurve input crashes

I have found crashes that happens when we use PolylineCurves as input to Grasshopper scripts sent to the /grasshopper endpoint.

The logs below are from a local installation when we use PolylineCurve as input, but the exact same thing happens on the https://compute.rhino3d.com endpoint.

2020-05-05T05:13:06.6292913-07:00 inf: frontend "POST /grasshopper" - "compute.rhino3d.js/1.0.0" {"RequestId": "58c4fe73-0d12-4c1d-bc8d-cab3e4fb8002", "Hostname": "0e9c36872645.", "UserHostAddress": "192.168.99.1", "RequestContentLength": 7640, "RequestContentType": "text/plain;charset=UTF-8", "Host": "192.168.99.90", "SourceContext": "Nancy.Request"}
2020-05-05T05:13:06.6292913-07:00 inf: frontend Stashed request to 58c4fe73-0d12-4c1d-bc8d-cab3e4fb8002 {}
2020-05-05T05:13:06.6292913-07:00 dbg: frontend Connection: ["close"] {}
2020-05-05T05:13:06.6292913-07:00 dbg: frontend Content-Length: ["7640"] {}
2020-05-05T05:13:06.6292913-07:00 dbg: frontend Content-Type: ["text/plain;charset=UTF-8"] {}
2020-05-05T05:13:06.6292913-07:00 dbg: frontend Accept: ["*/*;q=1"] {}
2020-05-05T05:13:06.6292913-07:00 dbg: frontend Accept-Encoding: ["gzip", "deflate"] {}
2020-05-05T05:13:06.6292913-07:00 dbg: frontend Host: ["192.168.99.90"] {}
2020-05-05T05:13:06.6292913-07:00 dbg: frontend User-Agent: ["compute.rhino3d.js/1.0.0"] {}

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at UnsafeNativeMethods.ON_Curve_IsPlanar(IntPtr pCurve, Boolean ignorePlane, Plane& plane, Double tolerance)
   at SurfaceComponents.SurfaceComponents.Component_BoundarySurfaces.ToPolyline(Curve curve)
   at SurfaceComponents.SurfaceComponents.Component_BoundarySurfaces.Compute(CurveList edges)
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
   at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

Test script:
computeTest.js.zip

Test data:
testFiles.zip

When I run the scripts I get the following results:
$ node ./computeTest.js hello_world_4.gh curve.3dm => OK
$ node ./computeTest.js hello_world_4.gh polyline.3dm => CRASH (with log as above)
$ node ./computeTest.js hello_world_4.gh curve.3dm => CRASH (without log)

It seems to me that NurbsCurve works well, but PolylineCurve does not. And furthermore, that after running into the error, the system is somehow in a bad state, since execution 1 and 3 has the same data but different results.

Is there something I am doing wrong or is this a bug?

Thanks,
Martin

File Watchers

Add file watchers for locally referenced definitions. When a file is modified, clear any cache of that file in compute

GH Solving Order and Dependent Disjoint SubGraphs

This is probably more of a documentation issue moreso than something necessary to develop.

  • There could be situations where a GH definition has disjoint subgraphs but still share some data, for example, in the case of the gh python sticky dictionary or some custom data scheme in a 3rd party dll. In these cases where the subgraphs depend on each other but there is no connection between components, we need to solve all of the subgraphs.
  • Related to above, GH/Compute will solve the outputs in the order in which they were created. So if there is a subgraph that stores some data, that should be solved first, and then the other subgraphs that might depend on that data. this can be worked around by creating the output params in the appropriate solving order.

Child process architecture

Redesign compute.geometry.exe to launch itself as children and proxy calls to these children. This will allow for multiple independent RhinoCore based processes on the same machine and allow for shutting down all RhinoCore based child processes while keeping the single top level process running. The single top level process should never actually load RhinoCore.

This design allows for shutting down Rhino and turning off core hour billing without completely turning off the service.

Update "Getting Started" guide

From conversations at AEC Tech last week it's apparent that the "Getting Started" guide needs reviewing. One major piece that appears to be missing is the installation of IIS.

Install-WindowsFeature -name Web-Server -IncludeManagementTools

I've gone through the process on a fresh Windows Server VM. Just need to go through and streamline the docs...

Deal with no server available situation

Hops components require a server to be available in order to solve. There are currently all sorts of problems that happen when a server is not available.

For local file system solves, launch child compute processes on Windows.
For other solves, provide error messages in the component

Grasshopper: Pipe component and definition error messages to server response

Currently there is no way for a person solving a gh definition to know what exactly went wrong. One could get around this by collecting component messages when the definition finishes solving, but trying to output this would trigger another definition solve (I think). Can this be handled by piping the component and definition messages to the web server response?

Compiling with Visual Studio Code

I couldn't run compute on Windows 10 (#109) and tried to compile it from source using VS Code. I did not succeed, because VS Code doesn't seem to understand .sln files and there are 652 problems, most likely missing dependencies in console.

Make Hops Task Capable

The Hops components will be commonly called with many iterations that could fan out to many different compute servers. Design the component's SolveInstance function to do this with multiple tasks. Use the IGH_TaskCapableComponent for this

Docker : Could not load file or assembly RhinoCommon or one of its dependencies

Dockerfile :

FROM mcr.microsoft.com/windows/servercore:ltsc2019
SHELL ["powershell", "-Command"]

# downloaded setup
COPY ["rhino_en-us_7.0.20098.14255.exe", "/"]
RUN Start-Process .\rhino_en-us_7.0.20098.14255.exe -ArgumentList '-package', '-quiet' -NoNewWindow -Wait
RUN Remove-Item .\rhino_en-us_7.0.20098.14255.exe

COPY ["55500d41-3a41-4474-99b3-684032a4f4df.lic", "C:/ProgramData/McNeel/Rhinoceros/6.0/License Manager/Licenses/"]
COPY ["cloudzoo.json", "C:/Users/ContainerAdministrator/AppData/Roaming/McNeel/Rhinoceros/6.0/License Manager/Licenses/"]
COPY ["settings-Scheme__Default.xml", "C:/Users/ContainerAdministrator/AppData/Roaming/McNeel/Rhinoceros/7.0/settings/"]

# I pasted the compute build here
COPY ["/app", "/app"]

WORKDIR /app

EXPOSE 80

CMD ["compute.frontend.exe"]

docker build works fine,
when doing a docker run I get this error repeatedly:

2020-04-17T12:08:39.6910241+05:30 dbg: frontend Logging to C:\Users\ContainerAdministrator\AppData\Local\Temp\Compute\Logs {}
2020-04-17T12:08:39.8628659+05:30 inf: frontend Configuration Result:
[Success] Name compute.frontend
[Success] ServiceName compute.frontend {"SourceContext": "Topshelf.HostFactory"}
2020-04-17T12:08:39.8628659+05:30 inf: frontend Topshelf v4.1.0.172, .NET Framework v4.0.30319.42000 {"SourceContext": "Topshelf.HostConfigurators.HostConfiguratorImpl"}
2020-04-17T12:08:39.8784913+05:30 dbg: frontend Running as a console application, creating the console host. {"SourceContext": "Topshelf.Builders.RunBuilder"}
2020-04-17T12:08:40.3473167+05:30 dbg: frontend Starting up as a console application {"SourceContext": "Topshelf.Hosts.ConsoleRunHost"}
2020-04-17T12:08:40.3628707+05:30 inf: frontend Starting back-end geometry service on port 8081 {}

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'RhinoCommon, Version=7.0.20007.12530, Culture=neutral, PublicKeyToken=552281e97c755530' or one of its dependencies. Invalid pointer (Exception from HRESULT: 0x80004003 (E_POINTER)) ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at RhinoInside.Resolver.get_RhinoSystemDirectory()
   at RhinoInside.Resolver.ResolveForRhinoAssemblies(Object sender, ResolveEventArgs args)
   at System.AppDomain.OnAssemblyResolveEvent(RuntimeAssembly assembly, String assemblyFullName)
   --- End of inner exception stack trace ---
   at compute.geometry.Program.LogVersions()
   at compute.geometry.Program.Main(String[] args) in C:\projects\compute-rhino3d\src\compute.geometry\Program.cs:line 31
2020-04-17T12:08:40.7534953+05:30 dbg: frontend ApplicationStartup {}
2020-04-17T12:08:40.7534953+05:30 inf: frontend Request stashing enabled via TempFileStasher {}
2020-04-17T12:08:40.8628659+05:30 inf: frontend Starting back-end geometry service on port 8081 {}
2020-04-17T12:08:40.9566167+05:30 inf: frontend compute.frontend running on http://localhost:80 {}
2020-04-17T12:08:40.9566167+05:30 inf: frontend The compute.frontend service is now running, press Control+C to exit. {"SourceContext": "Topshelf.Hosts.ConsoleRunHost"}

C# compute client should provide awaitable methods

Some functionality could take a while to solve and it would be nice if the C# client included awaitable methods to simplify backgrounding out of the box.

async void DoStuff(IEnumerable<Brep> breps)
{
  var union = await BrepCompute.CreateBooleanUnion(breps);
  // do more stuff
}

// or

var task = BrepCompute.CreateBooleanUnion(breps);
while (!task.Wait(250))
{
  // keep ui alive
  // check timeout
}
var res = task.Result;

We might need another namespace or an additional set of classes/methods, so as not to mess with anyone currently using the synchronous methods, e.g. using Rhino.ComputeAsync; or BrepComputeAsync.CreateBooleanUnion() or BrepCompute.CreateBooleanUnionAsync().

Karamba3d troubleshooting

Jotting down some notes on using the Karamba3d plug-in with Compute...

If you're running Compute on an OS with a graphical UI, e.g. Windows Server 2019, you can install Karamba and then run Rhino once to make sure that the Grasshopper plug-in will load when Compute runs.

If you don't have a desktop, e.g. Windows Server 1809 or Docker, then we need to do a little manual work. In order to load the Grasshopper plug-in, either

  • (a) ensure that the Rhino (licensing) plug-in is installed (see note below) and loaded (see #128), since the presence of this plug-in allows Grasshopper to find karamba.gha, or
  • (b) a "karamba.ghlink" file can be added to the Libraries folder that contains C:\Program Files\Rhino 7 WIP\Plug-Ins\Karamba.

Karamba's unattended installation guide doesn't include the LicensePlugin feature that will install the Karamba3DLicense plug-in.

I haven't yet figured out a way to load a network license, typically loaded using the Karamba3DGetLicense command, but it will work in either Free or Trial mode. Using a standalone license works.

Support cache flag in input scheme

Add a cache entry to the input scheme for compute. Compute can choose to use this to cache input/output combos instead of performing a solve

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.