Multiple Curve Splits error

Hi. I’m running into an issue when I try to split the curves with multiple intersections

Option 1 using parameters from the closest point method in the split method.

List<Curve> curveLines = new List<Curve>();
            
            for (int i = 0; i < inCurves.Count; i++)
            {
                List<Double> paramList = new List<Double>();
                for (int j = 0; j < eventPoints.Count; j++)
                {                  
                    //Find number of points on the curve and run loops to split based on the number of points
                    if (inCurves[i].ClosestPoint(eventPoints[j], out double param) == true)
                    {                                         
                        paramList.Add(param);
                    }

                }
                  var splitC1 = inCurves[i].Split(paramList);
                paramList.Clear();
                if (splitC1 != null)
                        {
                            var splitLines = splitC1.ToList();
                            for (int k = 0; k < splitLines.Count; k++)
                            {
                                var ccx_event = splitLines[k];
                                curveLines.Add(ccx_event);                             
                            }                 
                }
               
            }

inCurves the list of all curves for the intersection.
The left is 4 curves which i used for testing. The right is splits created after doing the above. you can see that the first curve breaks well but the rest breaks into smaller segments as the first. I am clearing the paramsList each time before the next split. Even then it retains the information I think.

Option 2 using parameters from curveIntersection method

for (int i=0;i<inCurves.Count-1;i++)
            {
                List<Double> eventParams = new List<Double>();
                for (int j = i + 1; j < inCurves.Count; j++)
                {
                    var eventsMultC = Rhino.Geometry.Intersect.Intersection.CurveCurve(inCurves[i], inCurves[j], doc.ModelAbsoluteTolerance, doc.ModelAbsoluteTolerance);

                    //var selfIntersect = Rhino.Geometry.Intersect.Intersection.CurveSelf(inCurves[i], doc.ModelAbsoluteTolerance);

                    if (eventsMultC != null)
                    {
                        for(int k = 0; k < eventsMultC.Count; k++)
                        {
                            var ccx_event = eventsMultC[k];
                            //eventPoints.Add(ccx_event.PointA);
                            if (ccx_event.PointA.DistanceTo(ccx_event.PointB) > double.Epsilon || ccx_event.PointA.DistanceTo(ccx_event.PointB) < double.Epsilon)
                            {
                                eventParams.Add(ccx_event.ParameterA);
                               
                            }
             
                        }
                    }
              
                }
                curveLines.AddRange(inCurves[i].Split(eventParams));
            }

the first curve has split but the rest did not split at all in the second option.

Not sure which is the best approach forward and how to get the curve split to work well.

Hi @sujal,

Without all your code, so we can run it ourselves, its difficult to know what’s going wrong.

Here is an example that I hope is helpful.

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  var go = new GetObject();
  go.SetCommandPrompt("Select curves to split");
  go.GeometryFilter = ObjectType.Curve;
  go.SubObjectSelect = false;
  go.GetMultiple(1, 0);
  if (go.CommandResult() != Result.Success)
    return go.CommandResult();

  var in_curves = new List<Curve>();
  foreach (var objref in go.Objects())
  {
    var curve = objref.Curve();
    if (null == curve)
      return Result.Failure;
    in_curves.Add(curve);
  }

  if (in_curves.Count < 2)
    return Result.Nothing;

  var tol = doc.ModelAbsoluteTolerance;

  for (var i = 0; i < in_curves.Count; i++)
  {
    var parameters = new List<double>();
    for (var j = 0; j < in_curves.Count; j++)
    {
      if (i != j)
      {
        var ccx_events = Intersection.CurveCurve(in_curves[i], in_curves[j], tol, tol);
        if (null != ccx_events)
        {
          foreach (var ccx in ccx_events)
          {
            if (ccx.IsPoint)
              parameters.Add(ccx.ParameterA);
          }
        }
      }
    }
 
    if (parameters.Count > 0)
    {
      parameters.Sort(); // sort
      var t = parameters.Distinct().ToList(); // cull
      var out_curves = in_curves[i].Split(t);
      if (null != out_curves)
      {
        foreach (var out_curve in out_curves)
          doc.Objects.AddCurve(out_curve);
      }
    }
  }

  foreach (var objref in go.Objects())
    doc.Objects.Delete(objref, false);

  doc.Views.Redraw();

  return Result.Success;
}

– Dale

1 Like

thank you @dale. This is super helpful. I got it working using the below code.

 protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            
            //To Select Center Lines
            ObjRef[] objrefs;
            Result rc = Rhino.Input.RhinoGet.GetMultipleObjects("Select set of Curves", false, ObjectType.Curve, out objrefs);
            if (rc != Rhino.Commands.Result.Success)
                return rc;
            if (objrefs == null || objrefs.Length < 1)
                return Rhino.Commands.Result.Failure;

            List<Curve> inCurves = new List<Curve>();
            for (int i = 0; i < objrefs.Length; i++)
            {
                Curve curve = objrefs[i].Curve();
                if (curve != null)
                    inCurves.Add(curve);
            }
List<Tuple<Curve, List<Curve>>> pairs = new List<Tuple<Curve, List<Curve>>>();

            for (int i = 0; i < inCurves.Count; i++)
            {
                var otherCurves = new List<Curve>();
                for (int j = 0; j < inCurves.Count; j++)
                {
                    if (i == j) continue;
                    otherCurves.Add(inCurves[j]);
                }
                pairs.Add(Tuple.Create(inCurves[i], otherCurves));
            }

            for (int i = 0; i < pairs.Count; i++)
            {
                List<Double> paramList = new List<Double>();
                for (int j = 0; j < pairs[i].Item2.Count; j++)
                {
                    var eventsMultC = Rhino.Geometry.Intersect.Intersection.CurveCurve(pairs[i].Item1, pairs[i].Item2[j], doc.ModelAbsoluteTolerance, doc.ModelAbsoluteTolerance);
                    if (eventsMultC == null) continue;
                    for (int k = 0; k < eventsMultC.Count; k++)
                    {
                        paramList.Add(eventsMultC[k].ParameterA);                     
                    }
                }
                curveLines.AddRange(pairs[i].Item1.Split(paramList));
            }
  foreach (var cur in curveLines)
                        {
                            doc.Objects.AddCurve(cur);
                        }

  doc.Views.Redraw();
            return Result.Success;
        }