Another Multi-Threaded Solid Difference Topic

Hi @michaelvollrath ,
The approach in my previous C# from 2018 I spread branches over threads by using DataTrees. I think the same technique can apply here. In the attached definition, I’ve modified it to use the List<Brep> overloads for the firstSet input of Brep.CreateBooleanDifference() instead of a single Brep.
20230907_Solid_Difference_Speed_Test_01b_BW.gh (23.9 KB)

  private void RunScript(DataTree<Brep> S, DataTree<Brep> D, ref object R)
  {
    double tolerance = doc.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(S.Paths, new System.Threading.Tasks.ParallelOptions
      { MaxDegreeOfParallelism = totalMaxConcurrancy},
      pth => {
      mainBrepsMT[pth] = Brep.CreateBooleanDifference(S.Branch(pth), D.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;

  }

The previous approach would return any problematic cutting Breps, however I haven’t tested this one to see if the whole thing fails with them. If it does, I could see allowing for a toggle to choose which method to use.

-Brian

4 Likes