// Function to create planes at each of the circles inorder to calculate the "interplane"
        //---------------------------------------------------------------------------------------

        public static Plane createPlane(Circle cp_circle, SpaceClaim.Api.V18.Geometry.Point cp_point1, SpaceClaim.Api.V18.Geometry.Point cp_point2, int cp_round, out bool cp_isreversed, out Vector cp_directionCyl)
        {
            Plane cp_plane = cp_circle.Plane;

            cp_directionCyl = cp_point1 - cp_point2;
            Vector cp_dir      = Vector.Create(Math.Round(cp_directionCyl.Direction.UnitVector.X, cp_round), Math.Round(cp_directionCyl.Direction.UnitVector.Y, cp_round), Math.Round(cp_directionCyl.Direction.UnitVector.Z, cp_round));
            Vector cp_planedir = Vector.Create(Math.Round(cp_plane.Frame.DirZ.UnitVector.X, cp_round), Math.Round(cp_plane.Frame.DirZ.UnitVector.Y, cp_round), Math.Round(cp_plane.Frame.DirZ.UnitVector.Z, cp_round));

            cp_isreversed = cp_dir.Direction.UnitVector == cp_planedir.Direction.UnitVector;
            return(cp_plane);
        }
        //function to split the cylinders by the interplane
        //-------------------------------------

        public static Body splitcylinder(Body sc_body, Plane sc_plane, SpaceClaim.Api.V18.Geometry.Point sc_point)
        {
            Body    sc_keepBody = null;
            Tracker sc_tracker  = null;

            sc_body.Split(sc_plane, sc_tracker);
            var sc_splitBodies = sc_body.SeparatePieces();

            foreach (Body sc_splitBody in sc_splitBodies)
            {
                if (sc_splitBody.ContainsPoint(sc_point))
                {
                    sc_keepBody = sc_splitBody;
                }
            }
            return(sc_keepBody);
        }
        //Function to rotate a plane by a give angle
        //------------------------------------------
        private static Plane rotatePlane(double rp_angle, Vector3D rp_vector1, Vector3D rp_axisunitvec, SpaceClaim.Api.V18.Geometry.Point rp_pointOnIntersection)
        {
            Vector3D  rp_rotatednorm = (rp_vector1 * Math.Cos(rp_angle)) + ((Vector3D.CrossProduct(rp_axisunitvec, rp_vector1)) * Math.Sin(rp_angle)) + (rp_axisunitvec * (Vector3D.DotProduct(rp_axisunitvec, rp_vector1)) * (1 - Math.Cos(rp_angle)));
            Direction rp_newNorm     = Direction.Create(rp_rotatednorm.X, rp_rotatednorm.Y, rp_rotatednorm.Z);
            Frame     rp_frame1      = Frame.Create(rp_pointOnIntersection, rp_newNorm);

            return(Plane.Create(rp_frame1));
        }
        //Function to create a plane mid way between two other planes
        //-----------------------------------------------------------

        public static Plane CreateInterPlane(Plane CIP_firstPlane, Plane CIP_secondPlane, bool CIP_normreversed1, bool CIP_normreversed2, out double CIP_angleBetweenPlane, out Vector3D CIP_unitvector3, out SpaceClaim.Api.V18.Geometry.Point CIP_pointOnIntersection)
        {
            Plane CIP_rotatedPlane = null;
            Plane CIP_outplane;

            CIP_angleBetweenPlane = 0;
            CIP_unitvector3       = new Vector3D();

            //Creates the Vector normals for the two planes inorder to do vector arithmetic
            Vector3D CIP_vector1 = new Vector3D(CIP_firstPlane.Frame.DirZ.X, CIP_firstPlane.Frame.DirZ.Y, CIP_firstPlane.Frame.DirZ.Z);
            Vector3D CIP_vector2 = new Vector3D(CIP_secondPlane.Frame.DirZ.X, CIP_secondPlane.Frame.DirZ.Y, CIP_secondPlane.Frame.DirZ.Z);

            //Creates the distance from the origin of the plane (d in the equation Ax+By+Cz+d=0)
            double CIP_d1 = -CIP_firstPlane.Frame.DirZ.X * CIP_firstPlane.Frame.Origin.X - CIP_firstPlane.Frame.DirZ.Y * CIP_firstPlane.Frame.Origin.Y - CIP_firstPlane.Frame.DirZ.Z * CIP_firstPlane.Frame.Origin.Z;
            double CIP_d2 = -CIP_secondPlane.Frame.DirZ.X * CIP_secondPlane.Frame.Origin.X - CIP_secondPlane.Frame.DirZ.Y * CIP_secondPlane.Frame.Origin.Y - CIP_secondPlane.Frame.DirZ.Z * CIP_secondPlane.Frame.Origin.Z;

            //Creates new Vector normal for the line of intersection of the two planes
            Vector3D CIP_vector3 = new Vector3D();

            CIP_vector3 = Vector3D.CrossProduct(CIP_vector1, CIP_vector2);

            //Creates a new unitvector which always points in a direction which means the rotation will go from 2-1
            if (CIP_normreversed1 == CIP_normreversed2)
            {
                CIP_unitvector3 = CIP_vector3 / CIP_vector3.Length;
            }
            else if (CIP_normreversed1 != CIP_normreversed2)
            {
                CIP_unitvector3 = -CIP_vector3 / CIP_vector3.Length;
            }

            //Works out point on the line of intersection
            Vector3D CIP_pointresult = Vector3D.CrossProduct((CIP_vector1 * CIP_d2 - CIP_vector2 * CIP_d1), CIP_vector3) / Vector3D.DotProduct(CIP_vector3, CIP_vector3);

            CIP_pointOnIntersection = SpaceClaim.Api.V18.Geometry.Point.Create(CIP_pointresult.X, CIP_pointresult.Y, CIP_pointresult.Z);

            //Works out the angle between the planes normals
            CIP_angleBetweenPlane = Math.Acos(Vector3D.DotProduct(CIP_vector1, CIP_vector2) / (CIP_vector1.Length * CIP_vector2.Length));

            //If the normals are both not revered or reversed change angle to 180 degree-angle
            if ((CIP_normreversed1 & CIP_normreversed2) | (CIP_normreversed1 == false & CIP_normreversed2 == false))
            {
                CIP_angleBetweenPlane = Math.PI - CIP_angleBetweenPlane;
            }
            double CIP_newangle = CIP_angleBetweenPlane / 2;

            //Works out the new normal of the plane mid way between the two using Rodrigues' Rotation formula and creates a new plane
            CIP_rotatedPlane = rotatePlane(CIP_newangle, CIP_vector2, CIP_unitvector3, CIP_pointOnIntersection);


            //Check to ensure that we are rotating the correct plane
            double   CIP_checkangle  = 0;
            Vector3D CIP_checkvector = new Vector3D(CIP_rotatedPlane.Frame.DirZ.X, CIP_rotatedPlane.Frame.DirZ.Y, CIP_rotatedPlane.Frame.DirZ.Z);

            if (CIP_normreversed1 == true)
            {
                CIP_checkangle = Math.Acos(Math.Abs(Vector3D.DotProduct(-CIP_vector1, CIP_checkvector)) / (CIP_vector1.Length * CIP_checkvector.Length));
            }
            else if (CIP_normreversed1 == false)
            {
                CIP_checkangle = Math.Acos(Math.Abs(Vector3D.DotProduct(CIP_vector1, CIP_checkvector)) / (CIP_vector1.Length * CIP_checkvector.Length));
            }
            //FileWriter("h:/test.out", "Angle Between planes " + CIP_angleBetweenPlane.ToString() + " Angle " + CIP_newangle.ToString() + " CheckAngle " + CIP_checkangle.ToString());
            if (CIP_checkangle >= CIP_angleBetweenPlane)
            {
                CIP_rotatedPlane = rotatePlane(CIP_newangle, CIP_vector1, CIP_unitvector3, CIP_pointOnIntersection);
            }

            return(CIP_outplane = Plane.Create(CIP_rotatedPlane.Frame));
        }
        // Function to create the cylindrical bodies
        //------------------------------------------

        public static Body createCylinder(Face cc_face, Face cc_startFace, Face cc_endFace, double cc_pipeRadius, int cc_i, int cc_MaxFaces, SpaceClaim.Api.V18.Geometry.Point cc_point1, SpaceClaim.Api.V18.Geometry.Point cc_point2)
        {
            //If the first face and the face is a torus draw out a cylindrical body
            if (cc_i == 0 && cc_face.GetGeometry <Torus>() != null)
            {
                double cc_length = cc_face.GetGeometry <Torus>().MajorRadius + cc_face.GetGeometry <Torus>().MinorRadius + 0.1;
                cc_length = cc_startFace.IsReversed ? cc_length : -cc_length;
                Body cc_newBody = Body.ExtrudeProfile(new CircleProfile(cc_startFace.GetGeometry <Plane>(), cc_pipeRadius), cc_length);
                return(cc_newBody);
            }

            //else if it is the end face and it is a torus also draw out a cylindrical body
            else if (cc_i == cc_MaxFaces - 1 && cc_face.GetGeometry <Torus>() != null)
            {
                double cc_length = cc_face.GetGeometry <Torus>().MajorRadius + cc_face.GetGeometry <Torus>().MinorRadius + 0.1;
                cc_length = cc_endFace.IsReversed ? cc_length : -cc_length;
                Body cc_newBody = Body.ExtrudeProfile(new CircleProfile(cc_endFace.GetGeometry <Plane>(), cc_pipeRadius), cc_length);
                return(cc_newBody);
            }

            //else draw out a cylinder
            else
            {
                Vector cc_deltad      = cc_point1 - cc_point2;
                Frame  cc_circleFrame = Frame.Create(cc_point2, cc_deltad.Direction);
                Plane  cc_circlePlane = Plane.Create(cc_circleFrame);

                Body cc_newBody = Body.ExtrudeProfile(new CircleProfile(cc_circlePlane, cc_pipeRadius), cc_deltad.Magnitude);
                return(cc_newBody);
            }
        }