BUG - Beta - C# - Script Component - Null Output

Hello,

The following code was working fine prior to the 10.10.23 Beta Update.

Now the code returns Null/Empty data output instead of the expected breps.

Graph Space:

Copy/Paste of the code works as expected in the older R7 C# component.

Please see the attached .gh file and let me know if there is anything I am doing wrong since the update regarding C# handling of outputs?

@eirannejad @wim

Thank you for your help!

script_component_c#_output_bug_01a.gh (20.0 KB)

Full Code:

// Grasshopper Script Instance
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;

using System.Linq;

public class Script_Instance : GH_ScriptInstance
{
  private void RunScript(DataTree<Brep> A, DataTree<Brep> B, out object R)
  {

    //Assign Tooltips
    Component.Name = "Solid Intersection (Multi-Threaded)";
    Component.NickName = "SIntMT";
    Component.Description = "A multi-threaded version of the Solid Intersection component";

    Component.Params.Input[0].Name = "Breps A";
    Component.Params.Input[0].NickName = "A";
    Component.Params.Input[0].Description = "First Set Of Breps";

    Component.Params.Input[1].Name = "Breps B";
    Component.Params.Input[1].NickName = "B";
    Component.Params.Input[1].Description = "Second Set Of Breps";

    Component.Params.Output[0].Name = "Result";
    Component.Params.Output[0].NickName = "R";
    Component.Params.Output[0].Description = "Solid Intersection Result";

    /////////////////////////////
    //written by Brian Washburn//
    //washburnarchitecture.com //
    //2023.09.08               //
    /////////////////////////////

    ////////////////////////////////
    //Modified by Michael Vollrath//
    //toyblock.co                 //
    //2023.09.23                  //
    ////////////////////////////////

    //Add Component Warnings Mimicking Native Component
    bool hasWarnings = false; // Flag to track if any warnings have been issued

    // Check if input A is null or empty
    if (A == null || A.DataCount == 0)
    {
        Component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input A Failed To Collect Data");
        hasWarnings = true;
    }

    // Check if input B is null or empty
    if (B == null || B.DataCount == 0)
    {
        Component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input B Failed To Collect Data");
        hasWarnings = true;
    }

    // If any warnings were issued, set R to null and return
    if (hasWarnings)
    {
        R = null;
        return;
    }

    double tolerance = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;

    var mainBrepsMT = new System.Collections.Concurrent.ConcurrentDictionary<GH_Path,List<Rhino.Geometry.Brep>> ();

    int totalMaxConcurrancy = System.Environment.ProcessorCount - 1;
    this.Component.Message = totalMaxConcurrancy + " Threads";


    //start of the parallel engine
    System.Threading.Tasks.Parallel.ForEach(A.Paths, new System.Threading.Tasks.ParallelOptions
    { MaxDegreeOfParallelism = totalMaxConcurrancy},
    pth => {
    mainBrepsMT[pth] = Brep.CreateBooleanIntersection(A.Branch(pth), B.Branch(pth), tolerance).ToList();
    });
    //end of the parallel engine

    //convert dictionaries to regular old data trees
    DataTree<Rhino.Geometry.Brep> mainBreps = new DataTree<Rhino.Geometry.Brep>();

    foreach(KeyValuePair<GH_Path,List<Rhino.Geometry.Brep>> p in mainBrepsMT)
    {
        mainBreps.AddRange(p.Value, p.Key);
    }

    R = mainBreps;
    // Iterate through the branches of mainBreps and print the number of intersections in each branch
    foreach (var path in mainBreps.Paths)
    {
        Console.WriteLine($"Branch {path}: {mainBreps.Branch(path).Count} intersections");
        Console.WriteLine("Type of mainBreps: " + mainBreps.GetType().FullName);
    }

  }
}

Try right clicking the component and then Avoid Marshalling Output Guids.

I’ve just spent the last two hours going back and forth between definitons to find out why some of my components didn’t work anymore and then accidently clicked that thing.

2 Likes

You’re my hero, thank you!

@eirannejad , is this the intended behavior?

2 Likes

Update:
Found the bug. big Ooops! definitely not the intended behaviour.

Rhino_cuRoJR0fdS

It should be working exactly how the legacy component should have worked. I just added the “Avoid Marshalling …” option so I might have messed up this one. I’ll get it tested and fixed.

Thank you :smiley:

3 Likes

Okay thank you! I’m glad it was only an oops! Thanks for clarifying

1 Like

For Future Reference:

RH-77658 Guid marshaller fails to convert DataTree<> of non Guid type

2 Likes

That actually makes sense! Thanks for sharing