private Result CreateTrapezoidFin(RhinoDoc doc, XmlNode compNd, double parentRadius, double xStart, double xEnd)
        {
            Result      result     = Rhino.Commands.Result.Failure;
            XmlElement  compEle    = compNd as XmlElement;
            XmlNodeList subCompNds = compNd.SelectNodes("subcomponents/*");

            int                  count           = 0;
            PositionType         positionType    = PositionType.Top;
            double               position        = 0;
            double               rotation        = 0;
            double               cant            = 0;
            double               thickness       = 0;
            double               rootChord       = 0;
            double               tipChord        = 0;
            double               sweepLength     = 0;
            double               height          = 0;
            double               tabHeight       = 0;
            double               tabLength       = 0;
            RelativePositionType tabPositionType = RelativePositionType.Front;
            double               tabPosition     = 0;
            List <Point3d>       points          = new List <Point3d>();

            foreach (XmlNode nd in compEle.ChildNodes)
            {
                if (nd.Name == "fincount")
                {
                    count = int.Parse(nd.InnerText);
                }
                else if (nd.Name == "thickness")
                {
                    thickness = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "rotation")
                {
                    rotation = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "position")
                {
                    position     = Double.Parse(nd.InnerText);
                    positionType = (PositionType)Enum.Parse(typeof(PositionType), ((XmlElement)nd).GetAttribute("type"), true);
                }
                else if (nd.Name == "cant")
                {
                    cant = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "tabheight")
                {
                    tabHeight = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "tablength")
                {
                    tabLength = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "tabposition")
                {
                    tabPosition     = Double.Parse(nd.InnerText);
                    tabPositionType = (RelativePositionType)Enum.Parse(typeof(RelativePositionType), ((XmlElement)nd).GetAttribute("relativeto"), true);
                }
                else if (nd.Name == "rootchord")
                {
                    rootChord = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "tipchord")
                {
                    tipChord = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "sweeplength")
                {
                    sweepLength = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "height")
                {
                    height = Double.Parse(nd.InnerText);
                }
            }

            points.Add(new Point3d(0, 0, 0));
            points.Add(new Point3d(sweepLength, height, 0));
            points.Add(new Point3d(sweepLength + tipChord, height, 0));
            points.Add(new Point3d(rootChord, 0, 0));

            CreateFinGeometry(doc, parentRadius, xStart, xEnd, ref result, count, positionType, position, cant, thickness, rootChord, tabHeight, ref tabLength, tabPositionType, points);

            return(result);
        }
        private static void CreateFinGeometry(RhinoDoc doc, double parentRadius, double xStart, double xEnd, ref Result result, int count, PositionType positionType, double position, double cant, double thickness, double rootChord, double tabHeight, ref double tabLength, RelativePositionType tabPositionType, List <Point3d> points)
        {
            if (tabHeight * tabLength > 0)
            {
                List <Point3d> tabPts          = new List <Point3d>(); // add points from aft end of fin.
                double         remainingLength = rootChord - tabLength;
                if (remainingLength < 0)
                {
                    tabLength       = rootChord;
                    remainingLength = 0;
                }

                switch (tabPositionType)
                {
                case RelativePositionType.Front:
                    tabPts.Add(new Point3d(points[0].X + tabLength, 0, 0));
                    tabPts.Add(new Point3d(points[0].X + tabLength, -tabHeight, 0));
                    tabPts.Add(new Point3d(points[0].X, -tabHeight, 0));
                    tabPts.Add(new Point3d(points[0].X, 0, 0));
                    break;

                case RelativePositionType.Center:
                    remainingLength /= 2;
                    tabPts.Add(new Point3d(points[0].X + tabLength + remainingLength, 0, 0));
                    tabPts.Add(new Point3d(points[0].X + tabLength + remainingLength, -tabHeight, 0));
                    tabPts.Add(new Point3d(points[0].X + remainingLength, -tabHeight, 0));
                    tabPts.Add(new Point3d(points[0].X + remainingLength, 0, 0));
                    tabPts.Add(new Point3d(points[0].X, 0, 0));
                    break;

                case RelativePositionType.End:
                    tabPts.Add(new Point3d(points[0].X + tabLength, 0, 0));
                    tabPts.Add(new Point3d(points[0].X + tabLength, -tabHeight, 0));
                    tabPts.Add(new Point3d(points[0].X + remainingLength, -tabHeight, 0));
                    tabPts.Add(new Point3d(points[0].X + remainingLength, 0, 0));

                    break;
                }
                points.AddRange(tabPts);
            }

            Brep brep = null;

            Polyline curve = new Polyline(points);

            double xLoc = 0;

            switch (positionType)
            {
            case PositionType.Top:
                xLoc = xStart + position;
                break;

            case PositionType.Bottom:
                xLoc = xEnd - rootChord + position;
                break;

            case PositionType.Middle:
                xLoc = (xEnd - xStart) / 2 + position;
                break;

            case PositionType.After:
                xLoc = xEnd + position;
                break;

            case PositionType.Absolute:
                xLoc = position;
                break;
            }

            List <Brep> breps = new List <Brep>();

            if (curve.IsClosed)
            {
                Extrusion ext = Extrusion.Create(curve.ToNurbsCurve(), thickness, true);
                brep = ext.ToBrep();

                Transform trans = Transform.Translation(new Vector3d(0, parentRadius, thickness / 2));
                brep.Transform(trans);
                trans = Transform.Rotation(cant * Math.PI / 180.0, Vector3d.YAxis, new Point3d(rootChord / 2, 0, 0));
                brep.Transform(trans);
                trans = Transform.Translation(new Vector3d(xLoc, 0, 0));
                brep.Transform(trans);
                breps.Add(brep);

                double deltaAng = 360 / count;

                for (int i = 1; i < count; i++)
                {
                    Transform copyTrans = Transform.Rotation(i * deltaAng * Math.PI / 180.0, Vector3d.XAxis, new Point3d(0, 0, 0));
                    Brep      newBrep   = brep.DuplicateBrep();
                    newBrep.Transform(copyTrans);
                    breps.Add(newBrep);
                }

                foreach (Brep brp in breps)
                {
                    if (doc.Objects.AddBrep(brp) != Guid.Empty)
                    {
                        result = Rhino.Commands.Result.Success;
                    }
                }

                doc.Views.Redraw();
            }
        }
        private Result CreateFreeFormFin(RhinoDoc doc, XmlNode compNd, double parentRadius, double xStart, double xEnd)
        {
            Result      result     = Rhino.Commands.Result.Failure;
            XmlElement  compEle    = compNd as XmlElement;
            XmlNodeList subCompNds = compNd.SelectNodes("subcomponents/*");

            int                  count           = 0;
            PositionType         positionType    = PositionType.Top;
            double               position        = 0;
            double               rotation        = 0;
            double               cant            = 0;
            double               thickness       = 0;
            double               tabHeight       = 0;
            double               tabLength       = 0;
            RelativePositionType tabPositionType = RelativePositionType.Front;
            double               tabPosition     = 0;
            List <Point3d>       points          = new List <Point3d>();

            foreach (XmlNode nd in compEle.ChildNodes)
            {
                if (nd.Name == "fincount")
                {
                    count = int.Parse(nd.InnerText);
                }
                else if (nd.Name == "thickness")
                {
                    thickness = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "rotation")
                {
                    rotation = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "position")
                {
                    position     = Double.Parse(nd.InnerText);
                    positionType = (PositionType)Enum.Parse(typeof(PositionType), ((XmlElement)nd).GetAttribute("type"), true);
                }
                else if (nd.Name == "cant")
                {
                    cant = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "tabheight")
                {
                    tabHeight = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "tablength")
                {
                    tabLength = Double.Parse(nd.InnerText);
                }
                else if (nd.Name == "tabposition")
                {
                    tabPosition     = Double.Parse(nd.InnerText);
                    tabPositionType = (RelativePositionType)Enum.Parse(typeof(RelativePositionType), ((XmlElement)nd).GetAttribute("relativeto"), true);
                }
                else if (nd.Name == "finpoints")
                {
                    foreach (XmlNode ptNd in nd.ChildNodes)
                    {
                        XmlElement ptEle = ptNd as XmlElement;
                        double     x     = Double.Parse(ptEle.GetAttribute("x"));
                        double     y     = Double.Parse(ptEle.GetAttribute("y"));
                        points.Add(new Point3d(x, y, 0.0));
                    }
                }
            }

            double rootChord = points[points.Count - 1].X - points[0].X;

            CreateFinGeometry(doc, parentRadius, xStart, xEnd, ref result, count, positionType, position, cant, thickness, rootChord, tabHeight, ref tabLength, tabPositionType, points);

            return(result);
        }