Split sphere problem - is there better way?

Thank you @jeremy5 and @martinsiegrist for your scripts and advices. I looked into it today. I was hoping for about 500ms to complete this operation, but it seems impossible.
What @anon39580149 recommended is exactly what I was looking for (and it’s a great collection of useful tools, so thanks for sharing!). But I would like to run my script on @shapediver and they just don’t support Sasquatch plugin.
So I tried hard with my limited knowledge of C# and came up with a messy buggy code that does the same, just somehow looses a few fragments somewhere on the way :smiley: And still it takes double time to compute than Sasquatch…

The code:

// set data tree for resulting fragments
DataTree<Brep> fragmentsTree = new DataTree<Brep>();

int branchIndex = 0;
double tolerance = 0.01;

// loop for each sphere (one sphere per each node)
foreach (List<Surface> spheres in S.Branches)
{
  Surface sphere = spheres[0];

  // set list for fragments of each of spheres
  List<Brep> fragments = new List<Brep>();
  // convert surface to brep
  Brep sphereBrep = Brep.CreateFromSurface(sphere);
  // add brep to list for first iteration
  fragments.Add(sphereBrep);

  // now take every plane in each branch and perform splitting process for fragments in the list
  foreach (Plane plane in P.Branch(branchIndex))
  {

    foreach(Brep fragment in fragments)
    {
      Curve[] intCurve = {};
      Point3d[] intPt = {};

      // intersect plane and brep to get splitting curve
      bool result = Rhino.Geometry.Intersect.Intersection.BrepPlane(fragment, plane, tolerance, out intCurve, out intPt);
      if (result) // some planes might not cut any fragment
      {

        // split fragment with curve
        Brep[] split = fragment.Split(intCurve, tolerance);
        // set temporary storage for fragments to pass to next iteration
        List<Brep> tempFragments = new List<Brep>();

        foreach (Brep testedFragment in split)
        {
          // get bounding box of tested fragment
          BoundingBox bBox = testedFragment.GetBoundingBox(plane);
          // get center point of that bbox
          Point3d center = bBox.Center;
          // evaluate if this center exists above or below the plane
          if (center.Z < 0)
          {
            // is the fragment is below the plane, add it to temporary storage
            tempFragments.Add(testedFragment);
          }

          // pass all "valid" fragments to the next nested iteration for further splitting
          fragments = tempFragments;
        }
      }
    }
  }

  // add residual portions of sphere to corresponding branch and iterate on next sphere
  GH_Path path = new GH_Path(branchIndex);
  fragmentsTree.AddRange(fragments, path);

  branchIndex += 1;
}

F = fragmentsTree;

The script: splitting spheres progress.gh (35.9 KB)