private void RunScript(List <System.Object> iWindingObjects, double iVecAmp, Curve iAxis, List <Curve> iSyntaxCurves, bool iBackSyntax, ref object oWindingObjects, ref object iTravelPlanes, ref object iAllPlanes)
    {
        // <Custom code>

        DataTree <Plane>    allPlanes      = new DataTree <Plane>();
        DataTree <Plane>    travelPlanes   = new DataTree <Plane>();
        GH_Path             pth            = new GH_Path(0);
        List <WindingClass> windingObjects = new List <WindingClass>();


        for (var index = 0; index < iWindingObjects.Count - 1; index++)
        {
            pth = new GH_Path(index);
            WindingClass wC = (WindingClass)iWindingObjects[index];
            wC.travelPath = CreateTravelPath(wC, (WindingClass)iWindingObjects[index + 1], iSyntaxCurves[index], iAxis, iVecAmp, iBackSyntax);
            travelPlanes.AddRange(wC.travelPath, pth);
            allPlanes.AddRange(wC.windingPath, pth);
            allPlanes.AddRange(wC.travelPath, pth);
            //allPlanes.AddRange(wC.transitionPath);
            windingObjects.Add(wC);
        }

        // Deal with last winding plane since it dosn't have two neighbors
        WindingClass lastItem = (WindingClass)iWindingObjects[iWindingObjects.Count - 1];

        allPlanes.AddRange(lastItem.windingPath, pth);
        windingObjects.Add((WindingClass)windingObjects.Last());

        oWindingObjects = windingObjects;
        iTravelPlanes   = travelPlanes;
        iAllPlanes      = allPlanes;

        // </Custom code>
    }
    private void RunScript(Polyline iPolyline, Surface iSrf, DataTree <Point3d> iAnchors, bool isBackSyntax, ref object oIsoCurves, ref object oWindingObjects, ref object oPlanes)

    {
        // <Custom code>

        List <WindingClass> windingPoints = new List <WindingClass>();
        List <Plane>        windingPlanes = new List <Plane>();
        List <Curve>        isoCurves     = new List <Curve>();

        for (int i = 0; i < iPolyline.Count; i++)
        {
            WindingClass tempWC = new WindingClass(iPolyline, i, iSrf, isBackSyntax, iAnchors);
            windingPoints.Add(tempWC);
            IdentifyPinIndexes(tempWC, iAnchors);
        }

        foreach (WindingClass wC in windingPoints)
        {
            windingPlanes.Add(wC.basePlane);
            isoCurves.Add(wC.iso);

            Print(wC.edgeIndex.ToString());
        }

        oWindingObjects = windingPoints;
        oPlanes         = windingPlanes;
        oIsoCurves      = isoCurves;

        // </Custom code>
    }
    // <Custom additional code>
    public void IdentifyPinIndexes(WindingClass wC, DataTree <Point3d> anchors)
    {
        // Find pin index

        double minDistancePin = double.MaxValue;

        for (var i = 0; i < anchors.Branch(wC.edgeIndex).Count; i++)
        {
            Point3d pt          = wC.basePlane.Origin;
            double  distancePin = pt.DistanceTo(anchors.Branch(wC.edgeIndex)[i]);
            if (distancePin < minDistancePin)
            {
                minDistancePin = distancePin;
                wC.pinIndex    = i;
            }
        }
    }
    private void RunScript(List <System.Object> iWindingObjects, ref object oWindingObjects, ref object oPlanes)
    {
        // <Custom code>
        List <Plane>        processedPlanes = new List <Plane>();
        List <WindingClass> windingObjects  = new List <WindingClass>();

        for (var index = 0; index < iWindingObjects.Count; index++)
        {
            WindingClass wC = (WindingClass)iWindingObjects[index];
            wC.attackAngle = AdjustAttackAngle(wC);
            processedPlanes.Add(wC.attackAngle);
            windingObjects.Add(wC);
        }

        oWindingObjects = windingObjects;
        oPlanes         = processedPlanes;


        // </Custom code>
    }
    // <Custom additional code>
    List <Plane> CreateTravelPath(WindingClass wC, WindingClass nextWC, Curve curve, Curve axis, double VecAmp, bool isBackSyntax)
    {
        List <Plane> path = new List <Plane>();

        Point3d[] geoDiv;
        int       divisionCount = 30;

        curve.DivideByCount(divisionCount, true, out geoDiv);
        //curve.DivideByLength(50, true, out geoDiv);
        curve.Domain = new Interval(0, 1);
        Point3d midPoint = axis.PointAt(0.55);

        for (int i = 0; i < geoDiv.Length - 1; i++)
        {
            double u;
            double v;
            wC.srf.ClosestPoint(geoDiv[i], out u, out v);
            Plane rpln;
            wC.srf.FrameAt(u, v, out rpln);
            double param;
            axis.ClosestPoint(geoDiv[i], out param);


            // Offset plane from surface
            Vector3d V = rpln.ZAxis;
            V.Unitize();

            Vector3d vec = V * VecAmp;
            rpln.Origin -= vec;



            // If is back syntax add vector that attracts the planes towards the middle

            if (true)

            {
                Vector3d toMid    = nextWC.basePlane.Origin - midPoint;
                Vector3d toMidNoZ = new Vector3d(toMid.X, toMid.Y, 0);

                Vector3d toMidCurrent    = wC.basePlane.Origin - midPoint;
                Vector3d toMidNoZCurrent = new Vector3d(toMidCurrent.X, toMidCurrent.Y, 0);

                Vector3d localToMid    = rpln.Origin - midPoint;
                Vector3d localToMidNoZ = new Vector3d(localToMid.X, localToMid.Y, 0);

                if (toMidNoZ.Length >= 1900)
                {
                    if (toMidNoZCurrent.Length >= 1900 && wC.edgeIndex != nextWC.edgeIndex)
                    {
                        localToMidNoZ += Vector3d.ZAxis * -100;
                        rpln.Origin   -= localToMidNoZ * 0.15;
                    }
                    else if (wC.edgeIndex != nextWC.edgeIndex)
                    {
                        rpln.Origin -= localToMidNoZ * 0.05;
                    }
                }
                else
                {
                    //rpln.Origin -= toMidNoZ * 0.1;
                }
            }



            Plane xyPlane = Plane.WorldXY;
            xyPlane.Origin = rpln.Origin;
            double distance = wC.basePlane.Origin.DistanceTo(nextWC.basePlane.Origin);

            // Universal Adjustments
            xyPlane.Rotate(RhinoMath.ToRadians(-90), xyPlane.ZAxis, xyPlane.Origin);
            xyPlane.Rotate(RhinoMath.ToRadians(-180), xyPlane.YAxis, xyPlane.Origin);



            int extremetiesThreshold = 1500;
            if (nextWC.basePlane.Origin.Y > wC.basePlane.Origin.Y)
            {
                // Rotate plane so robot is pulling fiber, reduces friction
                xyPlane.Rotate(RhinoMath.ToRadians(-45), xyPlane.YAxis, xyPlane.Origin);

                // Reorient if winding at extreme ends of component
                if (xyPlane.Origin.Y > extremetiesThreshold)
                {
                    xyPlane.Rotate(RhinoMath.ToRadians(-35), xyPlane.ZAxis, xyPlane.Origin);
                    xyPlane.Rotate(RhinoMath.ToRadians(-25), xyPlane.XAxis, xyPlane.Origin);
                }
                else if (xyPlane.Origin.Y < -extremetiesThreshold)
                {
                    xyPlane.Rotate(RhinoMath.ToRadians(35), xyPlane.ZAxis, xyPlane.Origin);
                }
            }
            else
            {
                // Rotate plane so robot is pulling fiber, reduces friction
                xyPlane.Rotate(RhinoMath.ToRadians(45), xyPlane.YAxis, xyPlane.Origin);

                // Reorient if winding at extreme ends of component
                if (xyPlane.Origin.Y < -extremetiesThreshold)
                {
                    xyPlane.Rotate(RhinoMath.ToRadians(35), xyPlane.ZAxis, xyPlane.Origin);
                    xyPlane.Rotate(RhinoMath.ToRadians(-25), xyPlane.XAxis, xyPlane.Origin);
                }
                else if (xyPlane.Origin.Y > extremetiesThreshold)
                {
                    xyPlane.Rotate(RhinoMath.ToRadians(-35), xyPlane.ZAxis, xyPlane.Origin);
                }
            }


            // Remove first few and last few travel planes

            if (i < 0 || i > divisionCount - 0)
            {
            }
            else
            {
                path.Add(xyPlane);
            }
        }
        return(path);
    }
    // <Custom additional code>
    Plane AdjustAttackAngle(WindingClass wp)
    {
        Vector3d tangent = wp.edgeCurve.TangentAt(wp.edgeParam);

        Plane tempPln;

        wp.edgeCurve.FrameAt(wp.edgeParam, out tempPln);

        Vector3d perpVector = Vector3d.CrossProduct(tangent, tempPln.YAxis);

        Plane npln = new Plane(wp.basePlane.Origin, perpVector, tangent);


        if (wp.edgeIndex == 1)
        {
            npln.Rotate(RhinoMath.ToRadians(180), npln.ZAxis);
            if (wp.edgeParam > 0.5)
            {
                npln.Rotate(RhinoMath.ToRadians(-105), npln.YAxis);
                npln.Rotate(RhinoMath.ToRadians(-90), npln.ZAxis);
                npln.Rotate(RhinoMath.ToRadians(-70), npln.XAxis);
            }
            else
            {
                npln.Rotate(RhinoMath.ToRadians(-105), npln.YAxis);
                npln.Rotate(RhinoMath.ToRadians(-90), npln.ZAxis);
                npln.Rotate(RhinoMath.ToRadians(-70), npln.XAxis);
                npln.Rotate(RhinoMath.ToRadians(60), npln.ZAxis);
            }
        }

        else if (wp.edgeIndex == 3)
        {
            npln = new Plane(wp.basePlane);
            npln.Rotate(RhinoMath.ToRadians(180), npln.XAxis);

            npln.Rotate(wp.edgeParam > 0.5 ? RhinoMath.ToRadians(50) : RhinoMath.ToRadians(70), npln.ZAxis);
        }
        else if (wp.edgeIndex == 2)
        {
            npln.Rotate(RhinoMath.ToRadians(90), npln.ZAxis);
            npln.Rotate(RhinoMath.ToRadians(180), npln.YAxis);
            npln.Rotate(RhinoMath.ToRadians(-80), npln.XAxis);
            if (wp.edgeParam < 0.25)
            {
                npln.Rotate(RhinoMath.ToRadians(-60), npln.ZAxis);
            }
            else if (wp.edgeParam < 0.5)
            {
                npln.Rotate(RhinoMath.ToRadians(-25), npln.ZAxis);
            }
            else if (wp.edgeParam > 0.5)
            {
                npln.Rotate(RhinoMath.ToRadians(35), npln.ZAxis);
                //npln.Rotate(RhinoMath.ToRadians(15), npln.XAxis);
            }
            //npln.Rotate(wp.edgeParam > 0.5 ? RhinoMath.ToRadians(65) : RhinoMath.ToRadians(-15), npln.ZAxis);
        }
        else if (wp.edgeIndex == 0)
        {
            npln.Rotate(RhinoMath.ToRadians(90), npln.ZAxis);
            npln.Rotate(RhinoMath.ToRadians(-90), npln.XAxis);
            npln.Rotate(wp.edgeParam > 0.5 ? RhinoMath.ToRadians(-25) : RhinoMath.ToRadians(25), npln.ZAxis);
        }

        // Check for vertical pins and reorient
        List <int> verticalPinsIds = new List <int>()
        {
            2, 6, 10, 14, 18, 22, 26, 30, 34, 38
        };

        if (wp.edgeIndex == 0)
        {
            bool isInList = verticalPinsIds.IndexOf(wp.pinIndex) != -1;
            if (isInList)
            {
                //npln.Rotate(RhinoMath.ToRadians(-110), npln.XAxis);
                //npln.Rotate(RhinoMath.ToRadians(180), npln.ZAxis);
                //if (wp.edgeParam < 0.3)
                //{
                //    npln.Rotate(RhinoMath.ToRadians(-45), npln.ZAxis);
                //    npln.Rotate(RhinoMath.ToRadians(-40), npln.YAxis);


                //}
                //else if (wp.edgeParam > 0.7)
                //{
                //    npln.Rotate(RhinoMath.ToRadians(45), npln.ZAxis);
                //    npln.Rotate(RhinoMath.ToRadians(-25), npln.XAxis);
                //    npln.Rotate(RhinoMath.ToRadians(35), npln.YAxis);
                //    npln.Rotate(RhinoMath.ToRadians(45), npln.ZAxis);
                //}
                //else
                //{
                //    npln.Rotate(RhinoMath.ToRadians(45), npln.ZAxis);
                //    npln.Rotate(RhinoMath.ToRadians(90), npln.YAxis);
                //    //npln.Rotate(RhinoMath.ToRadians(30), npln.XAxis);
                //    npln.Rotate(RhinoMath.ToRadians(45), npln.ZAxis);
                //}
                wp.isVertical = true;
            }
        }
        else if (wp.edgeIndex == 2)
        {
            bool isInList = verticalPinsIds.IndexOf(wp.pinIndex) != -1;
            if (isInList)
            {
                //npln.Rotate(RhinoMath.ToRadians(270), npln.YAxis);
                //npln.Rotate(RhinoMath.ToRadians(-90), npln.ZAxis);
                //if (wp.edgeParam < 0.3)
                //{
                //    npln.Rotate(RhinoMath.ToRadians(90), npln.YAxis);
                //    npln.Rotate(RhinoMath.ToRadians(-20), npln.ZAxis);
                //    npln.Rotate(RhinoMath.ToRadians(-40), npln.XAxis);



                //}
                //else if (wp.edgeParam > 0.7)
                //{
                //    npln.Rotate(RhinoMath.ToRadians(40), npln.ZAxis);
                //    npln.Rotate(RhinoMath.ToRadians(25), npln.YAxis);
                //    npln.Rotate(RhinoMath.ToRadians(-25), npln.XAxis);



                //}
                //else
                //{
                //    npln.Rotate(RhinoMath.ToRadians(-70), npln.XAxis);
                //    npln.Rotate(RhinoMath.ToRadians(45), npln.ZAxis);


                //}
                wp.isVertical = true;
            }
        }

        return(npln);
    }
    private void RunScript(List <System.Object> iWindingObjects, ref object oAngles)

    {
        // <Custom code>
        DataTree <double> positionerAngles = new DataTree <double>();

        for (var index = 0; index < iWindingObjects.Count - 1; index++)
        {
            GH_Path      pth = new GH_Path(index);
            WindingClass wp  = (WindingClass)iWindingObjects[index];

            if (wp.edgeIndex == 1)
            {
                if (wp.edgeParam > 0.5)
                {
                    positionerAngles.Add(-210, pth);
                }
                else
                {
                    positionerAngles.Add(-210, pth);
                }
            }
            else if (wp.edgeIndex == 3)
            {
                if (wp.edgeParam > 0.5)
                {
                    positionerAngles.Add(-245, pth);
                }
                else
                {
                    positionerAngles.Add(-205, pth);
                }
            }
            else if (wp.edgeIndex == 2)
            {
                if (wp.edgeParam > 0.65)
                {
                    positionerAngles.Add(-195, pth);
                }
                else if (wp.edgeParam < 0.25)
                {
                    positionerAngles.Add(-205, pth);
                }
                else
                {
                    positionerAngles.Add(-195, pth);
                }
            }
            else if (wp.edgeIndex == 0)
            {
                if (wp.edgeParam > 0.75)
                {
                    positionerAngles.Add(-205, pth);
                }
                else if (wp.edgeParam < 0.15)
                {
                    positionerAngles.Add(-220, pth);
                }
                else
                {
                    positionerAngles.Add(-195, pth);
                }
            }
        }

        oAngles = positionerAngles;
        // </Custom code>
    }