Getting started (dumb questions)


(Nathan Lowe) #1
  • what is the proper referencing of local libraries for code linting? - I’ve referenced RhinoCommon.dll
  • getting this exception on deserializing the response…

An unhandled exception of type ‘System.DllNotFoundException’ occurred in Newtonsoft.Json.dll
Additional information: Unable to load DLL ‘rhcommon_c’: The specified module could not be found. (Exception from HRESULT: 0x8007007E) occurred

Except I’m not sure how to reference the rhcommon_c.DLL


(Nathan Lowe) #2

I thought just having the DLLs together would enable referencing between the two.


(Steve Baer) #3

Hey Nathan,
You typically wouldn’t use RhinoCommon in your project for compute.rhino3d.com. You would use one of the Rhino3dmIO nuget packages and include the C# sdk source file in order to get compute access to functions that exist inside of RhinoCommon BUT NOT in Rhino3dmIO. I’ll try to slap a quick example together.

Note, you’ll also need to add a reference to JSON.NET in order for things to work.


(Nathan Lowe) #4

Got it. That was my initial setup… just swapped openNurbs for rhinocommon due to some issues… but let me check again.


(Nathan Lowe) #5

Steve now I’m getting the original error

An unhandled exception of type ‘System.BadImageFormatException’ occurred in Newtonsoft.Json.dll
Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) occurred


(Steve Baer) #6

You may need to force your application to be 64 bit (or prefer 64 bit). I’m not sure if we are still producing 32 bit versions of Rhino3dmIO. I’m checking on this.


(Nathan Lowe) #7

Awesome. That worked. I’m up and running! This is awesome!


(Nathan Lowe) #8

Steve, I can share my project with you if you’d like to have a quick start project.


(Steve Baer) #9

Are you using the Rhino6 version of Rhino3dmIO? That seemed to work for me without a problem.

This is what I’m using to test

using System;
using Rhino.Compute;

namespace MakeAMesh
{
  class Program
  {
    static void Main(string[] args)
    {
      ComputeServer.ApiToken = setyouremailaddresshere;
      var sphere = new Rhino.Geometry.Sphere(Rhino.Geometry.Point3d.Origin, 12);
      var sphereAsBrep = sphere.ToBrep();
      // above is just ordinary Rhino3dmIO calls
      // the next line is a call to the compute.rhino3d.com server
      var meshes = MeshCompute.CreateFromBrep(sphereAsBrep);

      // and back to using Rhinoe3dmIO locally
      Console.WriteLine($"Got {meshes.Length} meshes");
      for (int i = 0; i < meshes.Length; i++)
      {
        Console.WriteLine($"  {i + 1} mesh has {meshes[i].Vertices.Count} vrtices");
      }

      Console.WriteLine("press any key to exit");
      Console.ReadKey();
    }
  }
}

(Steve Baer) #10

I’ll create a repo where we can start dumping samples. Let me know what your github account is and I’ll make you a contributor. Thanks!! Very exciting.


(Nathan Lowe) #11

I’m using the latest publicly available nuget package 5.1.30000.25… that would probably explain why I had to comment out two methods in the RhinoCompute.cs But it’s working.


(Nathan Lowe) #12

my github account is: nadlowe

Thanks!


(Steve Baer) #13

That is old. There are V6 Rhino3dmIO libraries that you should be getting from nuget.


(Steve Baer) #14

I just created a repo at

and sent you an invite as a collaborator. Thanks


(Nathan Lowe) #15

Thanks!
Did a quick performance test to determine how I might overcome the performance hit of making a rest request for every Compute operation. Just as first swing I’m testing Parallel.Foreach due to simplicity.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Rhino.Compute;
using Rhino.Geometry;

namespace rhino_compute_tests
{
  class Program
  {
    static void Main()
    {
      RunApplication();
    }

    private static void RunApplication()
    {
      var listOfDims = Enumerable.Range(1, 100).ToList();

      var aggregateStopwatch = new Stopwatch();
      var aggregateLog = new StringBuilder();

      aggregateStopwatch.Start();

      Parallel.ForEach(listOfDims, dim =>
      {
        var eachStopwatch = new Stopwatch();
        var eachLog = new StringBuilder();

        eachStopwatch.Start();
        eachLog.AppendLine();

        var pt0 = new Point3d(-1, -1, -1);
        var pt1 = new Point3d(dim, dim, -1);
        var plane = new Plane(new Point3d(0, 0, -1), new Vector3d(0, 0, 1));
        var rectangle3D = new Rectangle3d(plane, pt0, pt1);
        var brep = Extrusion.Create(rectangle3D.ToNurbsCurve(), dim, true).ToBrep();

        var dimPlus = dim + 1;

        var linePt0 = new Point3d(-2, -2, -2);
        var linePt1 = new Point3d(dimPlus, dimPlus, dimPlus);

        var success = Rhino.Compute.Intersect.IntersectionCompute.CurveBrep(new LineCurve(linePt0, linePt1), brep, 0.0001, 0, out double[] intersections);

        if (success)
        {
          var intersectionHash = new HashSet<double>(intersections);
          foreach (var intersection in intersectionHash)
          {
            eachLog.AppendLine($"intersection at: {intersection}");
          }
        }
        else eachLog.AppendLine($"intersection operation unsuccessful!");

        eachStopwatch.Stop();

        eachLog.AppendLine();
        eachLog.AppendLine($"dim = {dim} volume = {brep.GetVolume()}");
        eachLog.AppendLine($"elapsed = {eachStopwatch.ElapsedMilliseconds} ms");

        aggregateLog.AppendLine(eachLog.ToString());
      });

      aggregateStopwatch.Stop();
      var elapsed = aggregateStopwatch.ElapsedMilliseconds;

      Console.WriteLine(aggregateLog.ToString());
      Console.WriteLine();
      Console.WriteLine($" aggregate elapsed = {elapsed} ms");
      Console.ReadKey();
    }
  }
}

Results 100 requests in 35 seconds.

intersection at: 1.73205080756888
intersection at: 107.38715006927

dim = 61 volume = 234484
elapsed = 1632 ms


intersection at: 1.73205080756888
intersection at: 3.46410161513775

dim = 1 volume = 4
elapsed = 5046 ms


intersection at: 1.73205080756888
intersection at: 45.0333209967908

dim = 25 volume = 16900
elapsed = 5256 ms


intersection at: 1.73205080756888
intersection at: 86.6025403784439

dim = 49 volume = 122500
elapsed = 5408 ms


intersection at: 1.73205080756888
intersection at: 65.8179306876173

dim = 37 volume = 53428
elapsed = 5700 ms


intersection at: 1.73205080756888
intersection at: 24.2487113059643

dim = 13 volume = 2548
elapsed = 5572 ms


intersection at: 1.73205080756888
intersection at: 128.171759760097

dim = 73 volume = 399748
elapsed = 6028 ms


intersection at: 1.73205080756888
intersection at: 148.956369450923

dim = 85 volume = 628660
elapsed = 5862 ms


intersection at: 1.73205080756888
intersection at: 5.19615242270663

dim = 2 volume = 18
elapsed = 5351 ms


intersection at: 1.73205080756888
intersection at: 169.74097914175

dim = 97 volume = 931587.999999999
elapsed = 6182 ms


intersection at: 1.73205080756888
intersection at: 25.9807621135332

dim = 14 volume = 3150
elapsed = 1575 ms


intersection at: 1.73205080756888
intersection at: 46.7653718043597

dim = 26 volume = 18954
elapsed = 1635 ms


intersection at: 1.73205080756888
intersection at: 109.119200876839

dim = 62 volume = 246078
elapsed = 1712 ms


intersection at: 1.73205080756888
intersection at: 6.92820323027551

dim = 3 volume = 48
elapsed = 1796 ms


intersection at: 1.73205080756888
intersection at: 88.3345911860127

dim = 50 volume = 130050
elapsed = 1872 ms


intersection at: 1.73205080756888
intersection at: 48.4974226119286

dim = 27 volume = 21168
elapsed = 1700 ms


intersection at: 1.73205080756888
intersection at: 67.5499814951862

dim = 38 volume = 57798
elapsed = 1816 ms


intersection at: 1.73205080756888
intersection at: 129.903810567666

dim = 74 volume = 416250
elapsed = 1820 ms


intersection at: 1.73205080756888
intersection at: 27.712812921102

dim = 15 volume = 3840
elapsed = 1778 ms


intersection at: 1.73205080756888
intersection at: 150.688420258492

dim = 86 volume = 650934
elapsed = 1752 ms


intersection at: 1.73205080756888
intersection at: 10.3923048454133

dim = 5 volume = 180
elapsed = 1795 ms


intersection at: 1.73205080756888
intersection at: 171.473029949319

dim = 98 volume = 960498
elapsed = 1732 ms


intersection at: 1.73205080756888
intersection at: 71.014083110324

dim = 40 volume = 67240
elapsed = 1812 ms


intersection at: 1.73205080756888
intersection at: 31.1769145362398

dim = 17 volume = 5508
elapsed = 2276 ms


intersection at: 1.73205080756888
intersection at: 91.7986928011505

dim = 52 volume = 146068
elapsed = 1946 ms


intersection at: 1.73205080756888
intersection at: 51.9615242270663

dim = 29 volume = 26100
elapsed = 2048 ms


intersection at: 1.73205080756888
intersection at: 110.851251684408

dim = 63 volume = 258048
elapsed = 2180 ms


intersection at: 1.73205080756888
intersection at: 8.66025403784439

dim = 4 volume = 100
elapsed = 2045 ms


intersection at: 1.73205080756888
intersection at: 90.0666419935816

dim = 51 volume = 137904
elapsed = 2052 ms


intersection at: 1.73205080756888
intersection at: 112.583302491977

dim = 64 volume = 270400
elapsed = 2307 ms


intersection at: 1.73205080756888
intersection at: 69.2820323027551

dim = 39 volume = 62400
elapsed = 2056 ms


intersection at: 1.73205080756888
intersection at: 50.2294734194974

dim = 28 volume = 23548
elapsed = 2268 ms


intersection at: 1.73205080756888
intersection at: 131.635861375235

dim = 75 volume = 433200
elapsed = 2078 ms


intersection at: 1.73205080756888
intersection at: 133.367912182804

dim = 76 volume = 450604
elapsed = 2328 ms


intersection at: 1.73205080756888
intersection at: 29.4448637286709

dim = 16 volume = 4624
elapsed = 2274 ms


intersection at: 1.73205080756888
intersection at: 12.1243556529821

dim = 6 volume = 294
elapsed = 2392 ms


intersection at: 1.73205080756888
intersection at: 152.420471066061

dim = 87 volume = 673728
elapsed = 2278 ms


intersection at: 1.73205080756888
intersection at: 173.205080756888

dim = 99 volume = 990000
elapsed = 2316 ms


intersection at: 1.73205080756888
intersection at: 72.7461339178928

dim = 41 volume = 72324
elapsed = 2308 ms


intersection at: 1.73205080756888
intersection at: 154.15252187363

dim = 88 volume = 697048
elapsed = 2404 ms


intersection at: 1.73205080756888
intersection at: 93.5307436087194

dim = 53 volume = 154548
elapsed = 2399 ms


intersection at: 1.73205080756888
intersection at: 32.9089653438087

dim = 18 volume = 6498
elapsed = 2608 ms


intersection at: 1.73205080756888
intersection at: 53.6935750346352

dim = 30 volume = 28830
elapsed = 2436 ms


intersection at: 1.73205080756888
intersection at: 174.937131564457

dim = 100 volume = 1020100
elapsed = 2664 ms


intersection at: 1.73205080756888
intersection at: 114.315353299546

dim = 65 volume = 283140
elapsed = 2841 ms


intersection at: 1.73205080756888
intersection at: 13.856406460551

dim = 7 volume = 448
elapsed = 2716 ms


intersection at: 1.73205080756888
intersection at: 96.9948452238571

dim = 55 volume = 172480
elapsed = 2688 ms


intersection at: 1.73205080756888
intersection at: 76.2102355330306

dim = 43 volume = 83248
elapsed = 2666 ms


intersection at: 1.73205080756888
intersection at: 121.243556529821

dim = 69 volume = 338100
elapsed = 2815 ms


intersection at: 1.73205080756888
intersection at: 135.099962990372

dim = 77 volume = 468468
elapsed = 2638 ms


intersection at: 1.73205080756888
intersection at: 55.4256258422041

dim = 31 volume = 31744
elapsed = 2814 ms


intersection at: 1.73205080756888
intersection at: 142.028166220648

dim = 81 volume = 544644
elapsed = 2689 ms


intersection at: 1.73205080756888
intersection at: 20.7846096908265

dim = 11 volume = 1584
elapsed = 2687 ms


intersection at: 1.73205080756888
intersection at: 34.6410161513775

dim = 19 volume = 7600
elapsed = 2828 ms


intersection at: 1.73205080756888
intersection at: 155.884572681199

dim = 89 volume = 720900
elapsed = 2790 ms


intersection at: 1.73205080756888
intersection at: 41.5692193816531

dim = 23 volume = 13248
elapsed = 2708 ms


intersection at: 1.73205080756888
intersection at: 74.4781847254617

dim = 42 volume = 77658
elapsed = 2717 ms


intersection at: 1.73205080756888
intersection at: 62.3538290724796

dim = 35 volume = 45360
elapsed = 2975 ms


intersection at: 1.73205080756888
intersection at: 95.2627944162882

dim = 54 volume = 163350
elapsed = 2635 ms


intersection at: 1.73205080756888
intersection at: 162.812775911474

dim = 93 volume = 821748
elapsed = 3041 ms


intersection at: 1.73205080756888
intersection at: 64.0858798800485

dim = 36 volume = 49284
elapsed = 3032 ms


intersection at: 1.73205080756888
intersection at: 83.1384387633061

dim = 47 volume = 108288
elapsed = 2751 ms


intersection at: 1.73205080756888
intersection at: 84.870489570875

dim = 48 volume = 115248
elapsed = 3004 ms


intersection at: 1.73205080756888
intersection at: 103.923048454133

dim = 59 volume = 212400
elapsed = 3023 ms


intersection at: 1.73205080756888
intersection at: 15.5884572681199

dim = 8 volume = 648
elapsed = 3044 ms


intersection at: 1.73205080756888
intersection at: 98.726896031426

dim = 56 volume = 181944
elapsed = 3104 ms


intersection at: 1.73205080756888
intersection at: 116.047404107115

dim = 66 volume = 296274
elapsed = 2974 ms


intersection at: 1.73205080756888
intersection at: 77.9422863405995

dim = 44 volume = 89100
elapsed = 3160 ms


intersection at: 1.73205080756888
intersection at: 124.707658144959

dim = 71 volume = 368064
elapsed = 3159 ms


intersection at: 1.73205080756888
intersection at: 136.832013797941

dim = 78 volume = 486798
elapsed = 3142 ms


intersection at: 1.73205080756888
intersection at: 122.97560733739

dim = 70 volume = 352870
elapsed = 3292 ms


intersection at: 1.73205080756888
intersection at: 126.439708952528

dim = 72 volume = 383688
elapsed = 3500 ms


intersection at: 1.73205080756888
intersection at: 143.760217028217

dim = 82 volume = 564898
elapsed = 3696 ms


intersection at: 1.73205080756888
intersection at: 22.5166604983954

dim = 12 volume = 2028
elapsed = 3635 ms


intersection at: 1.73205080756888
intersection at: 57.1576766497729

dim = 32 volume = 34848
elapsed = 3680 ms


intersection at: 1.73205080756888
intersection at: 36.3730669589464

dim = 20 volume = 8820
elapsed = 3635 ms


intersection at: 1.73205080756888
intersection at: 145.492267835786

dim = 83 volume = 585648
elapsed = 3916 ms


intersection at: 1.73205080756888
intersection at: 157.616623488768

dim = 90 volume = 745290
elapsed = 3662 ms


intersection at: 1.73205080756888
intersection at: 43.3012701892219

dim = 24 volume = 15000
elapsed = 4088 ms


intersection at: 1.73205080756888
intersection at: 166.276877526612

dim = 95 volume = 875520
elapsed = 3636 ms


intersection at: 1.73205080756888
intersection at: 147.224318643355

dim = 84 volume = 606900
elapsed = 4057 ms


intersection at: 1.73205080756888
intersection at: 164.544826719043

dim = 94 volume = 848350
elapsed = 3703 ms


intersection at: 1.73205080756888
intersection at: 105.655099261702

dim = 60 volume = 223260
elapsed = 2678 ms


intersection at: 1.73205080756888
intersection at: 168.008928334181

dim = 96 volume = 903264
elapsed = 3680 ms


intersection at: 1.73205080756888
intersection at: 17.3205080756888

dim = 9 volume = 900
elapsed = 3020 ms


intersection at: 1.73205080756888
intersection at: 79.6743371481684

dim = 45 volume = 95220
elapsed = 3019 ms


intersection at: 1.73205080756888
intersection at: 100.458946838995

dim = 57 volume = 191748
elapsed = 3004 ms


intersection at: 1.73205080756888
intersection at: 138.56406460551

dim = 79 volume = 505600
elapsed = 3049 ms


intersection at: 1.73205080756888
intersection at: 159.348674296337

dim = 91 volume = 770224
elapsed = 1868 ms


intersection at: 1.73205080756888
intersection at: 117.779454914684

dim = 67 volume = 309808
elapsed = 3256 ms


intersection at: 1.73205080756888
intersection at: 58.8897274573418

dim = 33 volume = 38148
elapsed = 2607 ms


intersection at: 1.73205080756888
intersection at: 38.1051177665153

dim = 21 volume = 10164
elapsed = 2585 ms


intersection at: 1.73205080756888
intersection at: 19.0525588832577

dim = 10 volume = 1210
elapsed = 1152 ms


intersection at: 1.73205080756888
intersection at: 81.4063879557372

dim = 46 volume = 101614
elapsed = 1099 ms


intersection at: 1.73205080756888
intersection at: 140.296115413079

dim = 80 volume = 524880
elapsed = 1136 ms


intersection at: 1.73205080756888
intersection at: 102.190997646564

dim = 58 volume = 201898
elapsed = 1398 ms


intersection at: 1.73205080756888
intersection at: 161.080725103906

dim = 92 volume = 795708
elapsed = 1135 ms


intersection at: 1.73205080756888
intersection at: 119.511505722253

dim = 68 volume = 323748
elapsed = 1120 ms


intersection at: 1.73205080756888
intersection at: 39.8371685740842

dim = 22 volume = 11638
elapsed = 1185 ms


intersection at: 1.73205080756888
intersection at: 60.6217782649107

dim = 34 volume = 41650
elapsed = 1120 ms



 aggregate elapsed = 35363 ms

This is building up to an ask about enabling the bulk send of requests to an endpoint via a queue.

I’m trying to propose a solution that minimizes your alls’ work. And uses the same automated API build, I’m assuming you’re using.

If it would be helpful, I could build a ConcurrentQueue and async method which packages all the requests per endpoint into an array of objects within the json payload (with an uuid appended to each)… then the endpoint code could keep its same automated build of just appending “/” to construct method addresses as it currently does… but there would need to be an additional extension method which could be another depth of endpoint or a header which enables submitting a package of requests to the endpoint. Then the API build code could use another Generic extension method to accept an array of results and respond back with an array of responses with the aforementioned ids.

On my side, each Post method would then block the return synchronously for the total async package result to return with all the results (I would set a max requests per package or a 500ms to 1 second timeout to send the package).

I can mockup my side of this… IF THIS SOUNDS WORTHWHILE :slight_smile: … but really until I can get response times within 300% of a native local machine method call… this will be just a demo project.


(Steve Baer) #16

Right now compute.rhino3d.com is a single moderately powered computer sitting somewhere like Virginia. It may make more sense to bring up a second computer on the west coast with a load balancer in front to see how that affects performance.

If you have something that you can mock up for your idea I would be interested in seeing it. I’m a little confused about what you are describing and something like a mock up may help.


(Steve Baer) #17

I’m also wondering how realistic of a use case this test is. There is a bit of overhead in serializing geometry to JSON format for communicating with compute.rhino3d.com. It may make more sense to come up with a new endpoint that accepts a single Brep and a list of curves or lines to compute intersections instead.


Swagger Api
(Nathan Lowe) #18

I’ll do a mock up…
I’m trying to prevent any manual per method additional work for you guys…

my test case is just a test case and does not represent the range of methods nor the specific type…

I totally recognize the I/O being heavier than the operation issue. But this is present in let’s say Grasshopper dataTrees as well… where each item in each branch runs a RhinoCommon method again…

basically my hunch is that the I/O overhead of the http request is significantly more limiting than the overhead of a running a method multiple times per request.


(Steve Baer) #19

This isn’t really a problem. The way I have things structured I would add a function to RhinoCommon that would become available in SR4. This same function would also become available on the compute server.

I appreciate it; thanks.


(Will Pearson) #20

For the benefit of anyone else reading this, you should be using one of the newer Rhino3dmIO nuget packages, like Rhino3dmIO.Desktop.