/// <summary>
        /// 生成曲面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonXBuild_Click(object sender, EventArgs e)
        {
            double attitudeL = this.doubleInputAttitudeLength.Value;
            double shapeR    = this.doubleInputShapeRadium.Value;

            // 生成产状数据集
            double       nx = 0.0, ny = 0.0, nz = 0.0;
            List <Point> sourceAttitudePoints = new List <Point>(this.targetMarkersList.Count * 4);

            foreach (var marker in this.targetMarkersList)
            {
                nx += Math.Sin(marker.MyDip * Math.PI / 180) * Math.Sin(marker.MyAngle * Math.PI / 180)
                      / this.targetMarkersList.Count;
                ny += Math.Cos(marker.MyDip * Math.PI / 180) * Math.Sin(marker.MyAngle * Math.PI / 180)
                      / this.targetMarkersList.Count;
                nz += Math.Cos(marker.MyAngle * Math.PI / 180) / this.targetMarkersList.Count;


                double dx         = -Math.Tan(marker.MyAngle * Math.PI / 180) * Math.Cos(marker.MyDip * Math.PI / 180);
                double dy         = -Math.Tan(marker.MyAngle * Math.PI / 180) * Math.Sin(marker.MyDip * Math.PI / 180);
                Point  northPoint = new Point(
                    marker.X,
                    marker.Y + attitudeL,
                    marker.Z + dy * attitudeL);
                Point southPoint = new Point(
                    marker.X,
                    marker.Y - attitudeL,
                    marker.Z - dy * attitudeL);
                Point eastPoint = new Point(
                    marker.X + attitudeL,
                    marker.Y,
                    marker.Z + dx * attitudeL);
                Point westPoint = new Point(
                    marker.X - attitudeL,
                    marker.Y,
                    marker.Z - dx * attitudeL);

                sourceAttitudePoints.AddRange(new[] { northPoint, southPoint, eastPoint, westPoint });
            }

            Point middlePoint = CurveAlgorithm.MiddlePointOfPoints(this.targetMarkersList);

            // 平均产状平面
            Vector3D n     = new Vector3D(nx, ny, nz);
            var      plane = new MathNet.Spatial.Euclidean.Plane(
                new Point3D(middlePoint.X, middlePoint.Y, middlePoint.Z),
                n.Normalize());

            double a0 = -plane.D / plane.C;
            double a1 = -plane.A / plane.C;
            double a2 = -plane.B / plane.C;

            // 插值点数据集
            List <Point> sourcePoints = new List <Point>(this.targetMarkersList);

            sourcePoints.AddRange(sourceAttitudePoints);

            SurfaceEquation surfaceEquation = new SurfaceEquation(a0, a1, a2, sourcePoints, shapeR);

            // 确定曲面区域
            List <Point> edgePoints = CurveAlgorithm.GetEdgePoints(sourcePoints, this.GridEdgeLength);

            // 区域内插加密点 GeoHelper.InsertPointsInPolygon
            List <Point> pointsList = GeoHelper.InsertPointsInPolygon(edgePoints, this.GridEdgeLength);

            // 生成网格 Triangulations
            Triangulations tris = new Triangulations(pointsList, new List <Point>());

            // 计算插值 SurfaceMesh
            tris.MeshSurface(surfaceEquation);

            // 绘制曲面
            IColor66 fillColor = this.sgworld.Creator.CreateColor(128, 128, 128, 128);
            IColor66 lineColor = this.sgworld.Creator.CreateColor(255, 255, 255, 0);

            var parentGid = GeoHelper.CreateGroup("产状地质曲面", ref this.sgworld);



            Facet facet = new Facet(ref this.sgworld, tris.TsData, "Test", parentGid, lineColor, fillColor);

            // facet.DrawFacet();

            // 保存三角网结果
            TsFile ts = new TsFile(
                tris.TsData,
                "TSurf",
                "M",
                "JGM",
                "Name",
                new List <string>());

            ts.WriteTsFile();
            ts.UpdateTsFile(ref this.db);

            ToastNotification.Show(this, "曲面模型已保存为模型部件", 2500, eToastPosition.MiddleCenter);
        }