using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Data.OleDb;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.UI;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB.Structure;

namespace uBIM_EarthTools
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    public class EarthLayerModel : IExternalCommand
    {
        public Result Execute(Autodesk.Revit.UI.ExternalCommandData CommandData, ref string Message, ElementSet elementset)
        {
            int page_index = 1;  //页面，每个excel文件不一样，应该要做个窗口下拉。从1算起。
            int x_column = 20;   //XY通常是反的，这里是按真实的XY读取
            int y_column = 19;
            int z_column = 2;    //“孔口标高”
            int begin_row = 1;   //从第几行开始是正式坐标数据。从1算起。            

            MessageBox.Show("当前Z坐标使用孔口绝对坐标。" + "\n" + "OK", "向日葵", MessageBoxButtons.OK);

            ////找两个孔口，用绝对坐标对应相对坐标。
            //XYZ p1_abs = new XYZ(16749485 / 304.8, 19953696 / 304.8, 5000 / 304.8);  //P1绝对坐标
            //XYZ p2_abs = new XYZ(16771342 / 304.8, 19940586/ 304.8, 5000 / 304.8);  //P2绝对坐标

            //XYZ p1_relative = new XYZ(-26559.4706 / 304.8, -5303.8028 / 304.8, 0);    //P1相对坐标
            //XYZ p2_relative = new XYZ(65390.1059 / 304.8, 1436.5661 / 304.8, 0);    //P2相对坐标

            XYZ p1_abs = XYZ.Zero;
            XYZ p2_abs = XYZ.BasisX;
            XYZ p1_relative = XYZ.Zero;
            XYZ p2_relative = XYZ.BasisX;

            double angle = -Math.PI * (ang_of_vector(p1_relative, p2_relative) - ang_of_vector(p1_abs, p2_abs)) / 180;

            Transform tf = Transform.Identity;
            tf.Origin = p1_relative - p1_abs;
            tf.BasisX = XYZ.BasisX;
            tf.BasisY = XYZ.BasisY;
            tf.BasisZ = XYZ.BasisZ;

            Transform tf2 = Transform.Identity;
            tf2.Origin = XYZ.Zero;
            tf2.BasisX = new XYZ(Math.Cos(angle), Math.Sin(angle), 0);
            tf2.BasisY = new XYZ(-Math.Sin(angle), Math.Cos(angle), 0);
            tf2.BasisZ = XYZ.BasisZ;

            Transform tf3 = Transform.Identity;
            tf3.Origin = p1_relative - tf2.Inverse.OfPoint(p1_relative);
            tf3.BasisX = XYZ.BasisX;
            tf3.BasisY = XYZ.BasisY;
            tf3.BasisZ = XYZ.BasisZ;

            Autodesk.Revit.ApplicationServices.Application Revit = CommandData.Application.Application;
            Autodesk.Revit.UI.UIDocument uidoc = CommandData.Application.ActiveUIDocument;
            Autodesk.Revit.DB.Document doc = CommandData.Application.ActiveUIDocument.Document;
            ICollection<ElementId> currentselectid = uidoc.Selection.GetElementIds();
            Autodesk.Revit.DB.View curview = doc.ActiveView;
            string tmppath = System.IO.Path.GetTempPath();
            List<string> delfile_list = new List<string>();

            //#region//求实体填充
            //ElementId solidid = ElementId.InvalidElementId;
            //IList<Element> fplist = (new FilteredElementCollector(doc)).OfClass(typeof(FillPatternElement)).ToElements();
            //foreach (Element ee in fplist)
            //{
            //    if (ee.Name == "实体填充")
            //    {
            //        solidid = ee.Id;
            //        break;
            //    }
            //    if (solidid == ElementId.InvalidElementId)
            //    {
            //        MessageBox.Show("找不到名为“实体填充”的填充样式，请先新建一个。", "向日葵", MessageBoxButtons.OK);
            //        return Autodesk.Revit.UI.Result.Succeeded;
            //    }
            //}
            //#endregion

            TransactionStatus status = TransactionStatus.Uninitialized;
            TransactionGroup transGroup = new TransactionGroup(doc, "地质建模");
            if (transGroup.Start() == TransactionStatus.Started)
            {
                #region//加共享参数-常规模型
                //String newfName = Revit.RecordingJournalFilename;
                //string sharepara_txt = "*META	VERSION	MINVERSION" + "\r\n";
                //sharepara_txt += "META	2	1" + "\r\n";
                //sharepara_txt += "*GROUP	ID	NAME" + "\r\n";
                //sharepara_txt += "GROUP	1	地质参数" + "\r\n";
                //sharepara_txt += "*PARAM	GUID	NAME	DATATYPE	DATACATEGORY	GROUP	VISIBLE	DESCRIPTION	USERMODIFIABLE" + "\r\n";
                //sharepara_txt += "PARAM" + "\t" + "11b28335-372f-479d-acf5-ddc3103cd76d" + "\t" + "孔号1" + "	TEXT		1	1		1" + "\r\n";
                //sharepara_txt += "PARAM" + "\t" + "64331fcb-5a1c-4f30-bc6c-4fae29921a9e" + "\t" + "孔号2" + "	TEXT		1	1		1" + "\r\n";
                //sharepara_txt += "PARAM" + "\t" + "85345026-1981-45b9-b1fb-460805a7d924" + "\t" + "孔号3" + "	TEXT		1	1		1" + "\r\n";

                //String fName = newfName.Substring(0, newfName.LastIndexOf("\\")) + "\\地质建模Para.txt";
                //StreamWriter sw = new StreamWriter(fName, false, Encoding.Unicode);
                //sw.Write(sharepara_txt);
                //sw.Close();

                //Revit.SharedParametersFilename = fName;
                //DefinitionFile sharedParametersFile_gm = Revit.OpenSharedParameterFile();
                //DefinitionGroup group_gm = sharedParametersFile_gm.Groups.get_Item("地质参数");

                //CategorySet catSet_gm = Revit.Create.NewCategorySet();
                //catSet_gm.Insert(doc.Settings.Categories.get_Item(BuiltInCategory.OST_GenericModel));
                //Autodesk.Revit.DB.Binding binding_gm = Revit.Create.NewInstanceBinding(catSet_gm);

                //Transaction transaction21 = new Transaction(doc, "共享参数");
                //transaction21.Start();
                //foreach (Definition df in group_gm.Definitions)
                //    doc.ParameterBindings.Insert(df, binding_gm);

                //transaction21.Commit();
                #endregion

                //加载族
                Transaction transaction = new Transaction(doc, "load the FamilySymbol");
                transaction.Start();
                IEnumerable<FamilySymbol> familysymbols_bj = from elem in new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol))
                                                             let fstmp = elem as FamilySymbol
                                                             where fstmp.Name.Contains("钻孔标记")
                                                             select fstmp;
                if (familysymbols_bj.Count() == 0)
                {
                    MessageBox.Show("请先加载配套的“钻孔标记”族。", "向日葵", MessageBoxButtons.OK);
                    status = transGroup.Assimilate();
                    return Result.Succeeded;
                }

                FamilySymbol fs_bj = doc.GetElement(familysymbols_bj.First().Id) as FamilySymbol;
                fs_bj.Activate();
                transaction.Commit();



                List<Solid> solid_list = new List<Solid>();
                List<point_six> point_six_list = new List<point_six>();
                List<String> layername_list = new List<String>();
                List<int> index1_list = new List<int>();
                List<int> index2_list = new List<int>();
                List<int> index3_list = new List<int>();
                List<String> kh1_list = new List<String>();
                List<String> kh2_list = new List<String>();
                List<String> kh3_list = new List<String>();
                List<XYZ> delta_list = new List<XYZ>();
                List<int> int_list = new List<int>();

                string pathstring = "";
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Title = "选择Excel文件…";
                //openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);//桌面路径     //注意这里写路径时要用c:\\而不是c:\
                openFileDialog.Filter = "文本文件|*.xls";
                openFileDialog.RestoreDirectory = false;
                openFileDialog.FilterIndex = 1;
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                    pathstring = openFileDialog.FileName;
                else
                    return Result.Succeeded;

                Microsoft.Office.Interop.Excel.Workbook wb = null;
                Microsoft.Office.Interop.Excel.Worksheet ws = null;

                //ArrayList columnArr = new ArrayList();//列字段表 
                //DataSet myDs = new DataSet();
                //System.Data.DataTable xlsTable = myDs.Tables.Add("show");
                object missing = System.Reflection.Missing.Value;
                Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();//lauch excel application
                excel.DisplayAlerts = false;
                if (excel != null)
                {
                    excel.Visible = true;
                    //excel.UserControl = true;
                    // 以只读的形式打开EXCEL文件
                    wb = excel.Workbooks.Open(pathstring, missing, true, missing, missing, missing,
                     missing, missing, missing, true, missing, missing, missing, missing, missing);
                    ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(page_index);

                    //取得总记录行数(包括标题列) 
                    int rowsint = ws.UsedRange.Rows.Count; //得到行数 
                    //int rowsint = begin_row + 2*10;
                    int columnsint = ws.UsedRange.Columns.Count;//得到列数 

                    List<string> name_list = new List<string>(); //string值集合（用来区分过滤器）
                    List<string> kh_list = new List<string>(); //孔号集合
                    List<XYZ> point_list = new List<XYZ>();
                    List<List<string>> str_list_list = new List<List<string>>();  //每一个点对应有一列string
                    List<List<XYZ>> point_list_list = new List<List<XYZ>>();      //每一个点对应有一列点，Z坐标不同

                    ////———————————————————测试数据——————————————————
                    //XYZ testpoint = new XYZ(double.Parse((ws.Cells[433, x_column]).Text.Replace("Y=", "")) * 1000 / 304.8,
                    //    double.Parse((ws.Cells[433, y_column]).Text.Replace("X=", "")) * 1000 / 304.8,
                    //    double.Parse((ws.Cells[433, z_column]).Text) * 1000 / 304.8);   //用以减小范围进行测试
                    //double testdistance = 10000 / 304.8;

                    for (int m = begin_row; m <= rowsint; m++)
                    {
                        if (ws.Cells[m, z_column].Text == "")
                            continue;
                        if (m / 2 != (m + 1) / 2)   //m为奇数
                        {
                            List<string> newstring_list = new List<string>();
                            List<XYZ> newpoint_list = new List<XYZ>();
                            double x = 0;
                            double y = 0;
                            double z = 0;

                            x = double.Parse((ws.Cells[m, x_column]).Text.Replace("Y=", "")) * 1000 / 304.8;
                            y = double.Parse((ws.Cells[m, y_column]).Text.Replace("X=", "")) * 1000 / 304.8;
                            z = double.Parse((ws.Cells[m, z_column]).Text) * 1000 / 304.8;


                            ////———————————————————测试数据——————————————————
                            //if ((new XYZ(x, y, z)).DistanceTo(testpoint) > testdistance)
                            //    continue;

                            //加上相对坐标转换
                            //要规避重复点，无语
                            if (point_list.Count > 0)
                            {
                                if (index_pointinlist(point_list, tf3.OfPoint(tf2.Inverse.OfPoint(tf.OfPoint(new XYZ(x, y, z)))), 0.1) != -1)
                                    continue;
                            }

                            point_list.Add(tf3.OfPoint(tf2.Inverse.OfPoint(tf.OfPoint(new XYZ(x, y, z)))));
                            newpoint_list.Add(tf3.OfPoint(tf2.Inverse.OfPoint(tf.OfPoint(new XYZ(x, y, z)))));

                            //第i个string对应第i个点与第i+1个点
                            for (int n = z_column + 1; n < Math.Min(x_column, y_column); n++)
                            {
                                string name = ws.Cells[m, n].Text.ToString();

                                if (!(name.Contains("0") || name.Contains("1") || name.Contains("2") || name.Contains("3") || name.Contains("4") ||
                                    name.Contains("5") || name.Contains("6") || name.Contains("7") || name.Contains("8") || name.Contains("9") || name.Contains("10")))
                                    continue;

                                if (name == "")
                                    continue;
                                if (name == "1")
                                    name += " SAND";
                                if (name == "2")
                                    name += " MUD";
                                if (name == "3")
                                    name += " CLAY";
                                if (name == "4")
                                    name += " Medium-Coarse SAND";
                                if (name == "5")
                                    name += " Sandy SILT";
                                if (name == "6")
                                    name += " Clayey SAND";
                                if (name == "7")
                                    name += " GRANITE";
                                if (name == "8")
                                    name += " Coarse SAND";
                                if (name == "9")
                                    name += " Silty SAND";
                                if (name == "10")
                                    name += " Sandy CLAY";

                                if (ws.Cells[m, n].Text != "")
                                {
                                    if (!name_list.Contains(name))
                                        name_list.Add(name);
                                    newstring_list.Add(name);
                                    try
                                    {
                                        //double zp = z - double.Parse((ws.Cells[m + 1, n]).Text) * 1000 / 304.8;         //相对Z坐标
                                        double zp = double.Parse((ws.Cells[m + 1, n]).Text) * 1000 / 304.8;         //绝对Z坐标
                                        newpoint_list.Add(tf3.OfPoint(tf2.Inverse.OfPoint(tf.OfPoint(new XYZ(x, y, zp)))));
                                    }
                                    catch
                                    {
                                        //MessageBox.Show((ws.Cells[m, n]).Text + "\n" + m + "\n" + n, "向日葵", MessageBoxButtons.OK);
                                    }
                                }
                            }
                            str_list_list.Add(newstring_list);
                            point_list_list.Add(newpoint_list);
                            kh_list.Add(ws.Cells[m, 1].Text);
                        }
                    }



                    #region 所有点的bbox建楼板求三角剖分
                    //MessageBox.Show(str_list_list[0][0] + "\n" + str_list_list[0][1], "向日葵", MessageBoxButtons.OK);
                    //求包络外框                    
                    double x_min = point_list[0].X; double x_max = point_list[0].X;
                    double y_min = point_list[0].Y; double y_max = point_list[0].Y;
                    double z_mmm = point_list[0].Z + 1000 / 304.8;

                    foreach (XYZ p in point_list)
                    {
                        if (p.X > x_max)
                            x_max = p.X;
                        if (p.X < x_min)
                            x_min = p.X;
                        if (p.Y > y_max)
                            y_max = p.Y;
                        if (p.Y < y_min)
                            y_min = p.Y;
                    }

                    x_min -= 20000 / 304.8;
                    y_min -= 20000 / 304.8;
                    x_max += 20000 / 304.8;
                    y_max += 20000 / 304.8;

                    XYZ left_bottom = new XYZ(x_min, y_min, z_mmm);
                    XYZ right_top = new XYZ(x_max, y_max, z_mmm);

                    //建楼板
                    Curve c1 = Line.CreateBound(new XYZ(x_min, y_min, z_mmm), new XYZ(x_max, y_min, z_mmm));
                    Curve c2 = Line.CreateBound(new XYZ(x_max, y_min, z_mmm), new XYZ(x_max, y_max, z_mmm));
                    Curve c3 = Line.CreateBound(new XYZ(x_max, y_max, z_mmm), new XYZ(x_min, y_max, z_mmm));
                    Curve c4 = Line.CreateBound(new XYZ(x_min, y_max, z_mmm), new XYZ(x_min, y_min, z_mmm));
                    CurveArray ca = new CurveArray();
                    ca.Append(c1); ca.Append(c2); ca.Append(c3); ca.Append(c4);
                    Transaction transaction40 = new Transaction(doc, "yy"); transaction40.Start();
                    Floor floor = doc.Create.NewFloor(ca, true);
                    transaction40.Commit();

                    //求三角剖分
                    Transaction transaction2 = new Transaction(doc, "yy");
                    FailureHandlingOptions failureHandlingOptions2 = transaction2.GetFailureHandlingOptions();
                    FailureHandler failureHandler2 = new FailureHandler();
                    failureHandlingOptions2.SetFailuresPreprocessor(failureHandler2);
                    failureHandlingOptions2.SetClearAfterRollback(true);
                    transaction2.SetFailureHandlingOptions(failureHandlingOptions2);
                    transaction2.Start();
                    int k = -1;
                    foreach (XYZ p in point_list)
                    {
                        k = (-1) * k;
                        XYZ newp = new XYZ(p.X, p.Y, p.Z + k * 1000 / 304.8);
                        SlabShapeEditor sse = floor.SlabShapeEditor;
                        sse.DrawPoint(newp);
                    }
                    transaction2.Commit();

                    List<Curve> curve_list = new List<Curve>();
                    SlabShapeEditor sse_ok = floor.SlabShapeEditor;
                    foreach (SlabShapeCrease ssc in sse_ok.SlabShapeCreases)
                    {
                        Curve cc = Line.CreateBound(new XYZ(ssc.Curve.GetEndPoint(0).X, ssc.Curve.GetEndPoint(0).Y, 0),
                           new XYZ(ssc.Curve.GetEndPoint(1).X, ssc.Curve.GetEndPoint(1).Y, 0));
                        curve_list.Add(cc);
                    }
                    #endregion


                    //先放标记
                    Transaction transaction35 = new Transaction(doc, "yy"); transaction35.Start();
                    for (int i = 0; i <= point_list.Count - 1; i++)
                    {
                        FamilyInstance fi_bj = doc.Create.NewFamilyInstance(point_list[i], fs_bj, StructuralType.NonStructural);
                        fi_bj.LookupParameter("孔号").Set(kh_list[i]);
                    }
                    transaction35.Commit();

                    //地形建模

                    #region 求三角面,List<int[3]> itr_list
                    List<int[]> itr_list = new List<int[]>();
                    for (int i = 0; i <= point_list.Count - 3; i++)
                    {
                        for (int t = i + 1; t <= point_list.Count - 2; t++)
                        {
                            XYZ p1 = point_list[i];
                            XYZ p2 = point_list[t];
                            XYZ p10 = new XYZ(p1.X, p1.Y, 0);
                            XYZ p20 = new XYZ(p2.X, p2.Y, 0);

                            if (p10.DistanceTo(p20) > 100000 / 304.8)   //大于50米不考虑连接
                                continue;

                            if (p10.DistanceTo(p20) < 0.1)
                                continue;

                            for (int r = t + 1; r <= point_list.Count - 1; r++)
                            {
                                XYZ p3 = point_list[r];
                                XYZ p30 = new XYZ(p3.X, p3.Y, 0);

                                //三点接近共线的要去掉
                                if (p30.DistanceTo(p10) < 0.1)
                                    continue;
                                if (p30.DistanceTo(p20) < 0.1)
                                    continue;
                                Line line1 = Line.CreateUnbound(p10, p20 - p10);
                                Line line2 = Line.CreateUnbound(p20, p30 - p20);
                                Line line3 = Line.CreateUnbound(p30, p10 - p30);
                                double d1 = line1.Project(p30).Distance / p10.DistanceTo(p20);
                                double d2 = line2.Project(p10).Distance / p20.DistanceTo(p30);
                                double d3 = line3.Project(p20).Distance / p30.DistanceTo(p10);
                                if (Math.Min(Math.Min(d1, d2), d3) < 0.02)
                                    continue;

                                //三点组成的三角形里面，如果有其他点的，要去掉。这条比较阴险。
                                int cl = clockwise(p10, p20, p30);
                                Boolean insidetriangle = false;
                                for (int gg = 0; gg <= point_list.Count - 1; gg++)
                                {
                                    if (gg == i || gg == t || gg == r)
                                        continue;
                                    XYZ p4 = point_list[gg];
                                    XYZ p40 = new XYZ(p4.X, p4.Y, 0);
                                    if (p4.X >= Math.Max(Math.Max(p1.X, p2.X), p3.X) || p4.X <= Math.Min(Math.Min(p1.X, p2.X), p3.X))
                                        continue;
                                    if (p4.Y >= Math.Max(Math.Max(p1.Y, p2.Y), p3.Y) || p4.Y <= Math.Min(Math.Min(p1.Y, p2.Y), p3.Y))
                                        continue;
                                    if (clockwise(p40, p10, p20) == cl && clockwise(p40, p20, p30) == cl && clockwise(p40, p30, p10) == cl)
                                    {
                                        insidetriangle = true;
                                        break;
                                    }
                                }
                                if (insidetriangle)
                                    continue;


                                if (p30.DistanceTo(p10) > 100000 / 304.8 || p30.DistanceTo(p20) > 100000 / 304.8)   //大于50米不考虑连接
                                    continue;

                                Curve ctmp1 = null;
                                Curve ctmp2 = null;
                                Curve ctmp3 = null;
                                for (int a = 0; a <= curve_list.Count - 1; a++)
                                {
                                    if (curve_list[a].GetEndPoint(0).DistanceTo(p10) < 0.01 && curve_list[a].GetEndPoint(1).DistanceTo(p20) < 0.01)
                                        ctmp1 = curve_list[a];
                                    if (curve_list[a].GetEndPoint(1).DistanceTo(p10) < 0.01 && curve_list[a].GetEndPoint(0).DistanceTo(p20) < 0.01)
                                        ctmp1 = curve_list[a];
                                    if (curve_list[a].GetEndPoint(0).DistanceTo(p10) < 0.01 && curve_list[a].GetEndPoint(1).DistanceTo(p30) < 0.01)
                                        ctmp2 = curve_list[a];
                                    if (curve_list[a].GetEndPoint(1).DistanceTo(p10) < 0.01 && curve_list[a].GetEndPoint(0).DistanceTo(p30) < 0.01)
                                        ctmp2 = curve_list[a];
                                    if (curve_list[a].GetEndPoint(0).DistanceTo(p20) < 0.01 && curve_list[a].GetEndPoint(1).DistanceTo(p30) < 0.01)
                                        ctmp3 = curve_list[a];
                                    if (curve_list[a].GetEndPoint(1).DistanceTo(p20) < 0.01 && curve_list[a].GetEndPoint(0).DistanceTo(p30) < 0.01)
                                        ctmp3 = curve_list[a];
                                }
                                if (ctmp1 != null && ctmp2 != null && ctmp3 != null)
                                {
                                    //现在有三个int：i、t、r，互相连接
                                    int[] itr = new int[3];
                                    itr[0] = i;
                                    itr[1] = t;
                                    itr[2] = r;
                                    itr_list.Add(itr);
                                }
                            }
                        }
                    }
                    #endregion

                    foreach (int[] itr in itr_list)
                    {
                        int i = itr[0];
                        int t = itr[1];
                        int r = itr[2];

                        //MessageBox.Show(kh_list[i] + "\n" + kh_list[t] + "\n" + kh_list[r], "向日葵", MessageBoxButtons.OK);

                        List<XYZ> xyz_i = point_list_list[i];
                        List<XYZ> xyz_t = point_list_list[t];
                        List<XYZ> xyz_r = point_list_list[r];

                        List<string> str_i = str_list_list[i];
                        List<string> str_t = str_list_list[t];
                        List<string> str_r = str_list_list[r];

                        List<int> int_i_list = new List<int>();   //蛋糕顶层，i列已经用了的index
                        List<int> int_t_list = new List<int>();   //t列已经用了的index
                        List<int> int_r_list = new List<int>();   //r列已经用了的index
                        List<int> int_ii_list = new List<int>();  //对应的蛋糕底层
                        List<int> int_tt_list = new List<int>();
                        List<int> int_rr_list = new List<int>();

                        //从高到低依次检测各段，从i开始
                        #region //先将三列均有的找出来
                        for (int qi = 0; qi < str_i.Count; qi++)
                        {
                            int index_i = qi;
                            int index_ii = qi + 1;
                            int index_t = -1;
                            int index_tt = -1;
                            int index_r = -1;
                            int index_rr = -1;
                            string layername = str_i[qi];

                            for (int qt = 0; qt < str_t.Count; qt++)
                            {
                                if (int_t_list.Contains(qt))
                                    continue;
                                if (str_t[qt] != layername)
                                    continue;
                                if ((xyz_i[qi].Z - xyz_t[qt].Z) / xyz_i[qi].DistanceTo(xyz_t[qt]) < 0.5)
                                {
                                    index_t = qt;
                                    index_tt = qt + 1;
                                    break;
                                }
                            }
                            for (int qr = 0; qr < str_r.Count; qr++)
                            {
                                if (int_r_list.Contains(qr))
                                    continue;
                                if (str_r[qr] != layername)
                                    continue;
                                if ((xyz_i[qi].Z - xyz_r[qr].Z) / xyz_i[qi].DistanceTo(xyz_r[qr]) < 0.5)
                                {
                                    index_r = qr;
                                    index_rr = qr + 1;
                                    break;
                                }
                            }

                            if (index_t != -1 && index_r != -1)
                            {
                                layername_list.Add(layername);
                                int_i_list.Add(index_i);
                                int_t_list.Add(index_t);
                                int_r_list.Add(index_r);
                                int_ii_list.Add(index_ii);
                                int_tt_list.Add(index_tt);
                                int_rr_list.Add(index_rr);
                            }
                        }
                        #endregion

                        #region //再找另两列没有的
                        for (int qqi = 0; qqi < str_i.Count; qqi++)
                        {
                            if (int_i_list.Contains(qqi))
                                continue;

                            int index_i = qqi;
                            int index_ii = qqi + 1;
                            int index_t = -1;
                            int index_tt = -1;
                            int index_r = -1;
                            int index_rr = -1;
                            string layername = str_i[qqi];

                            int t_begin = 0;
                            int t_end = xyz_t.Count - 1;
                            int r_begin = 0;
                            int r_end = xyz_r.Count - 1;

                            //————————————————————————————————
                            //求int_ii_list中，小于qqi且最接近的 ，对应的int_tt_list即为t_begin

                            int min1 = 100; int min3 = 100;
                            int abc1 = -1; int abc3 = -1;
                            for (int bb = 0; bb <= int_ii_list.Count - 1; bb++)
                            {
                                if (int_ii_list[bb] <= qqi && qqi - int_ii_list[bb] <= min1 && int_tt_list[bb] >= t_begin)
                                {
                                    min1 = qqi - int_ii_list[bb];
                                    t_begin = int_tt_list[bb];
                                    //r_begin = int_rr_list[bb];
                                    abc1 = int_ii_list[bb];
                                }
                            }
                            for (int bb = 0; bb <= int_ii_list.Count - 1; bb++)
                            {
                                if (int_ii_list[bb] <= qqi && qqi - int_ii_list[bb] <= min3 && int_rr_list[bb] >= r_begin)
                                {
                                    min3 = qqi - int_ii_list[bb];
                                    //t_begin = int_tt_list[bb];
                                    r_begin = int_rr_list[bb];
                                    abc3 = int_ii_list[bb];
                                }
                            }


                            //求int_i_list中，大于qqi且最接近的 ，对应的int_t_list即为t_end
                            int min2 = 100; int min4 = 100;
                            int abc2 = -1; int abc4 = 100;
                            for (int bb = 0; bb <= int_i_list.Count - 1; bb++)
                            {
                                if (int_i_list[bb] <= abc1)
                                    continue;
                                if (int_i_list[bb] >= qqi && int_i_list[bb] - qqi <= min2 && int_t_list[bb] <= t_end)
                                {
                                    min2 = int_i_list[bb] - qqi;
                                    t_end = int_t_list[bb];
                                    //r_end = int_r_list[bb];
                                    abc2 = int_i_list[bb];
                                }
                            }
                            for (int bb = 0; bb <= int_i_list.Count - 1; bb++)
                            {
                                if (int_i_list[bb] <= abc3)
                                    continue;
                                if (int_i_list[bb] >= qqi && int_i_list[bb] - qqi <= min4 && int_r_list[bb] <= r_end)
                                {
                                    min4 = int_i_list[bb] - qqi;
                                    //t_end = int_t_list[bb];
                                    r_end = int_r_list[bb];
                                    abc4 = int_i_list[bb];
                                }
                            }

                            //————————————————————————————————                            

                            List<XYZ> tmp_t = new List<XYZ>();
                            for (int qt = 0; qt < str_t.Count; qt++)
                            {
                                if (qt >= t_begin && qt <= t_end)
                                {
                                    if (str_t[qt] == layername && !int_t_list.Contains(qt))
                                    {
                                        index_t = qt;
                                        index_tt = qt + 1;
                                        break;
                                    }
                                    else
                                        tmp_t.Add(xyz_t[qt]);
                                }
                            }

                            if (tmp_t.Count == 0)
                                tmp_t.Add(xyz_t[xyz_t.Count - 1]);   //这一句有点冒险

                            if (index_t == -1)
                            {
                                index_t = index_pointinlist(xyz_t, tmp_t[index_pz_nearest(tmp_t, xyz_i[qqi])], 0.001);
                                index_tt = index_t;
                            }

                            List<XYZ> tmp_r = new List<XYZ>();
                            for (int qr = 0; qr < str_r.Count; qr++)
                            {
                                if (qr >= r_begin && qr <= r_end)
                                {
                                    if (str_r[qr] == layername && !int_r_list.Contains(qr))
                                    {
                                        index_r = qr;
                                        index_rr = qr + 1;
                                        break;
                                    }
                                    else
                                        tmp_r.Add(xyz_r[qr]);
                                }
                            }

                            if (tmp_r.Count == 0)
                                tmp_r.Add(xyz_r[xyz_r.Count - 1]);   //这一句有点冒险

                            if (index_r == -1)
                            {
                                index_r = index_pointinlist(xyz_r, tmp_r[index_pz_nearest(tmp_r, xyz_i[qqi])], 0.001);
                                index_rr = index_r;
                            }

                            layername_list.Add(layername);
                            int_i_list.Add(index_i);
                            int_t_list.Add(index_t);
                            int_r_list.Add(index_r);
                            int_ii_list.Add(index_ii);
                            int_tt_list.Add(index_tt);
                            int_rr_list.Add(index_rr);
                        }
                        #endregion

                        #region //t列未处理的段落
                        for (int qqt = 0; qqt < str_t.Count; qqt++)
                        {
                            if (int_t_list.Contains(qqt))
                            {
                                int ttmmpp = int_t_list.IndexOf(qqt);
                                if (int_tt_list[ttmmpp] == qqt + 1)
                                    continue;
                            }

                            int index_i = -1;
                            int index_ii = -1;
                            int index_t = qqt;
                            int index_tt = qqt + 1;
                            int index_r = -1;
                            int index_rr = -1;
                            string layername = str_t[qqt];

                            int i_begin = 0;
                            int i_end = xyz_i.Count - 1;
                            int r_begin = 0;
                            int r_end = xyz_r.Count - 1;

                            //————————————————————————————————
                            //求int_tt_list中，小于qqt且最接近的 ，对应的int_ii_list即为i_begin
                            int min1 = 100; int min3 = 100;
                            int abc1 = -1; int abc3 = -1;
                            for (int bb = 0; bb <= int_tt_list.Count - 1; bb++)
                            {
                                if (int_tt_list[bb] <= qqt && qqt - int_tt_list[bb] <= min1 && int_ii_list[bb] >= i_begin)
                                {
                                    min1 = qqt - int_tt_list[bb];
                                    i_begin = int_ii_list[bb];
                                    //r_begin = int_rr_list[bb];
                                    abc1 = int_tt_list[bb];
                                }
                            }
                            for (int bb = 0; bb <= int_tt_list.Count - 1; bb++)
                            {
                                if (int_tt_list[bb] <= qqt && qqt - int_tt_list[bb] <= min3 && int_rr_list[bb] >= r_begin)
                                {
                                    min3 = qqt - int_tt_list[bb];
                                    //i_begin = int_ii_list[bb];
                                    r_begin = int_rr_list[bb];
                                    abc3 = int_tt_list[bb];
                                }
                            }


                            //求int_t_list中，大于qqt且最接近的 ，对应的int_i_list即为i_end
                            int min2 = 100; int min4 = 100;
                            for (int bb = 0; bb <= int_t_list.Count - 1; bb++)
                            {
                                if (int_t_list[bb] <= abc1)
                                    continue;
                                if (int_t_list[bb] >= qqt && int_t_list[bb] - qqt <= min2 && int_i_list[bb] <= i_end)
                                {
                                    min2 = int_t_list[bb] - qqt;
                                    i_end = int_i_list[bb];
                                    //r_end = int_r_list[bb];
                                }
                            }
                            for (int bb = 0; bb <= int_t_list.Count - 1; bb++)
                            {
                                if (int_t_list[bb] <= abc3)
                                    continue;
                                if (int_t_list[bb] >= qqt && int_t_list[bb] - qqt <= min4 && int_r_list[bb] <= r_end)
                                {
                                    min4 = int_t_list[bb] - qqt;
                                    r_end = int_r_list[bb];
                                }
                            }

                            //MessageBox.Show(qqt + "\n" + i_begin + "\n" + i_end, "向日葵", MessageBoxButtons.OK);
                            //————————————————————————————————

                            List<XYZ> tmp_i = new List<XYZ>();
                            for (int qi = 0; qi < xyz_i.Count; qi++)
                            {
                                if (qi >= i_begin && qi <= i_end)
                                    tmp_i.Add(xyz_i[qi]);
                            }

                            if (tmp_i.Count == 0)
                                tmp_i.Add(xyz_i[xyz_i.Count - 1]);   //这一句有点冒险

                            if (index_i == -1)
                            {
                                //MessageBox.Show(tmp_i.Count + "\n" + "OK", "向日葵", MessageBoxButtons.OK);
                                index_i = index_pointinlist(xyz_i, tmp_i[index_pz_nearest(tmp_i, xyz_t[qqt])], 0.001);
                                index_ii = index_i;
                            }

                            List<XYZ> tmp_r = new List<XYZ>();
                            for (int qr = 0; qr < xyz_r.Count; qr++)
                            {
                                if (qr >= r_begin && qr <= r_end)
                                    tmp_r.Add(xyz_r[qr]);
                            }

                            if (tmp_r.Count == 0)
                                tmp_r.Add(xyz_r[xyz_r.Count - 1]);   //这一句有点冒险

                            if (index_r == -1)
                            {
                                index_r = index_pointinlist(xyz_r, tmp_r[index_pz_nearest(tmp_r, xyz_t[qqt])], 0.001);
                                index_rr = index_r;
                            }

                            layername_list.Add(layername);
                            int_i_list.Add(index_i);
                            int_t_list.Add(index_t);
                            int_r_list.Add(index_r);
                            int_ii_list.Add(index_ii);
                            int_tt_list.Add(index_tt);
                            int_rr_list.Add(index_rr);
                        }
                        #endregion

                        #region //r列未处理的段落
                        for (int qqr = 0; qqr < str_r.Count; qqr++)
                        {
                            if (int_r_list.Contains(qqr))
                            {
                                int ttmmpp = int_r_list.IndexOf(qqr);
                                if (int_rr_list[ttmmpp] == qqr + 1)
                                    continue;
                            }

                            int index_i = -1;
                            int index_ii = -1;
                            int index_t = -1;
                            int index_tt = -1;
                            int index_r = qqr;
                            int index_rr = qqr + 1;
                            string layername = str_r[qqr];

                            int i_begin = 0;
                            int i_end = xyz_i.Count - 1;
                            int t_begin = 0;
                            int t_end = xyz_t.Count - 1;

                            //————————————————————————————————
                            //求int_rr_list中，小于qqr且最接近的 ，对应的int_ii_list即为i_begin
                            int min1 = 100; int min3 = 100;
                            int abc1 = -1; int abc3 = -1;
                            for (int bb = 0; bb <= int_rr_list.Count - 1; bb++)
                            {
                                if (int_rr_list[bb] <= qqr && qqr - int_rr_list[bb] <= min1 && int_ii_list[bb] >= i_begin)
                                {
                                    min1 = qqr - int_rr_list[bb];
                                    i_begin = int_ii_list[bb];
                                    abc1 = int_rr_list[bb];
                                }
                                if (int_rr_list[bb] <= qqr && qqr - int_rr_list[bb] <= min3 && int_tt_list[bb] >= t_begin)
                                {
                                    min3 = qqr - int_rr_list[bb];
                                    t_begin = int_tt_list[bb];
                                    abc3 = int_rr_list[bb];
                                }
                            }

                            //求int_t_list中，大于qqt且最接近的 ，对应的int_i_list即为i_end
                            int min2 = 100; int min4 = 100;
                            for (int bb = 0; bb <= int_r_list.Count - 1; bb++)
                            {
                                if (int_r_list[bb] <= abc1)
                                    continue;
                                if (int_r_list[bb] >= qqr && int_r_list[bb] - qqr <= min2 && int_i_list[bb] <= i_end)
                                {
                                    min2 = int_r_list[bb] - qqr;
                                    i_end = int_i_list[bb];
                                }
                            }
                            for (int bb = 0; bb <= int_r_list.Count - 1; bb++)
                            {
                                if (int_r_list[bb] <= abc3)
                                    continue;
                                if (int_r_list[bb] >= qqr && int_r_list[bb] - qqr <= min4 && int_t_list[bb] <= t_end)
                                {
                                    min4 = int_r_list[bb] - qqr;
                                    t_end = int_t_list[bb];
                                }
                            }

                            //————————————————————————————————

                            List<XYZ> tmp_i = new List<XYZ>();
                            for (int qi = 0; qi < xyz_i.Count; qi++)
                            {
                                if (qi >= i_begin && qi <= i_end)
                                    tmp_i.Add(xyz_i[qi]);
                            }

                            if (tmp_i.Count == 0)
                                tmp_i.Add(xyz_i[xyz_i.Count - 1]);   //这一句有点冒险

                            if (index_i == -1)
                            {
                                index_i = index_pointinlist(xyz_i, tmp_i[index_pz_nearest(tmp_i, xyz_r[qqr])], 0.001);
                                index_ii = index_i;
                            }

                            List<XYZ> tmp_t = new List<XYZ>();
                            for (int qt = 0; qt < xyz_t.Count; qt++)
                            {
                                if (qt >= t_begin && qt <= t_end)
                                    tmp_t.Add(xyz_t[qt]);
                            }
                            if (index_t == -1)
                            {
                                index_t = index_pointinlist(xyz_t, tmp_t[index_pz_nearest(tmp_t, xyz_r[qqr])], 0.001);
                                index_tt = index_t;
                            }

                            layername_list.Add(layername);
                            int_i_list.Add(index_i);
                            int_t_list.Add(index_t);
                            int_r_list.Add(index_r);
                            int_ii_list.Add(index_ii);
                            int_tt_list.Add(index_tt);
                            int_rr_list.Add(index_rr);
                        }
                        #endregion


                        #region //做蛋糕
                        for (int s = 0; s < int_i_list.Count; s++)
                        {
                            XYZ delta = xyz_i[int_i_list[s]];
                            //XYZ p1a = xyz_i[int_i_list[s]] - delta;
                            //XYZ p2a = xyz_t[int_t_list[s]] - delta;
                            //XYZ p3a = xyz_r[int_r_list[s]] - delta;
                            //XYZ p1b = xyz_i[int_ii_list[s]] - delta;
                            //XYZ p2b = xyz_t[int_tt_list[s]] - delta;
                            //XYZ p3b = xyz_r[int_rr_list[s]] - delta;

                            XYZ p1a = xyz_i[int_i_list[s]];
                            XYZ p2a = xyz_t[int_t_list[s]];
                            XYZ p3a = xyz_r[int_r_list[s]];
                            XYZ p1b = xyz_i[int_ii_list[s]];
                            XYZ p2b = xyz_t[int_tt_list[s]];
                            XYZ p3b = xyz_r[int_rr_list[s]];

                            if (p1a.IsAlmostEqualTo(p1b) && p2a.IsAlmostEqualTo(p2b) && p3a.IsAlmostEqualTo(p3b))  //为什么会有这种情况？
                                continue;

                            //double fix = Math.Max(Math.Max(Math.Abs(p1a.Z - p2a.Z), Math.Abs(p2a.Z - p3a.Z)), Math.Abs(p3a.Z - p1a.Z));

                            if (p1a.IsAlmostEqualTo(p1b))
                                p1b += new XYZ(0, 0, -0.01);
                            if (p2a.IsAlmostEqualTo(p2b))
                                p2b += new XYZ(0, 0, -0.01);
                            if (p3a.IsAlmostEqualTo(p3b))
                                p3b += new XYZ(0, 0, -0.01);

                            Curve curve1a = Line.CreateBound(p1a, p2a);
                            Curve curve2a = Line.CreateBound(p2a, p3a);
                            Curve curve3a = Line.CreateBound(p3a, p1a);
                            Curve curve1b = Line.CreateBound(p1b, p2b);
                            Curve curve2b = Line.CreateBound(p2b, p3b);
                            Curve curve3b = Line.CreateBound(p3b, p1b);

                            CurveLoop cla = new CurveLoop();
                            CurveLoop clb = new CurveLoop();

                            cla.Append(curve1a); cla.Append(curve2a); cla.Append(curve3a);
                            clb.Append(curve1b); clb.Append(curve2b); clb.Append(curve3b);

                            //Transaction trans = new Transaction(doc);

                            //string tmp_fName = string.Empty;
                            //try
                            //{

                            //    tmp_fName += "地质" + layername_list[(s)] + "层";
                            //}
                            //catch (Exception)
                            //{
                            //    TaskDialog.Show("Show", layername_list.Count.ToString() + "\r\n" + (s - 1));
                            //}

                            //Family family = (new FilteredElementCollector(doc)
                            //  .OfCategory(BuiltInCategory.OST_GenericModel)
                            //  .OfClass(typeof(FamilySymbol)).Where(x => x.Name == "自适应地质块").First() as FamilySymbol).Family;
                            //Autodesk.Revit.DB.Document fdoc = doc.EditFamily(family);
                            //Transaction transs = new Transaction(fdoc);

                            //if (null != fdoc)
                            //{
                            //    transs.Start("faq");
                            //    FamilyManager fm = fdoc.FamilyManager;
                            //    try
                            //    {
                            //        FamilyType ft = fm.NewType(tmp_fName);

                            //    }
                            //    catch (Exception)
                            //    {
                            //    }




                            //    transs.Commit();
                            //}
                            //LoadOpts loadOptions = new LoadOpts();
                            //family = fdoc.LoadFamily(doc, loadOptions);

                            //trans.Start("11");
                            //FamilySymbol symbol1 = new FilteredElementCollector(doc)
                            //  .OfCategory(BuiltInCategory.OST_GenericModel)
                            //  .OfClass(typeof(FamilySymbol)).Where(x => x.Name == tmp_fName).First() as FamilySymbol;
                            //foreach (Element me in mtset2)
                            //{
                            //    if (me.Name == layername_list[s])
                            //    {
                            //        symbol1.LookupParameter("材质").Set(me.Id);
                            //        break;
                            //    }
                            //}


                            //if (AdaptiveComponentInstanceUtils.IsAdaptiveFamilySymbol(symbol1))
                            //{
                            //    FamilyInstance familyInstance = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, symbol1);
                            //    IList<ElementId> plist = AdaptiveComponentInstanceUtils.GetInstancePointElementRefIds(familyInstance);
                            //    ReferencePoint referencePoint = doc.GetElement(plist.ElementAt(0)) as ReferencePoint;
                            //    ReferencePoint referencePoint1 = doc.GetElement(plist.ElementAt(1)) as ReferencePoint;
                            //    ReferencePoint referencePoint2 = doc.GetElement(plist.ElementAt(2)) as ReferencePoint;
                            //    ReferencePoint referencePoint3 = doc.GetElement(plist.ElementAt(3)) as ReferencePoint;
                            //    ReferencePoint referencePoint4 = doc.GetElement(plist.ElementAt(4)) as ReferencePoint;
                            //    ReferencePoint referencePoint5 = doc.GetElement(plist.ElementAt(5)) as ReferencePoint;
                            //    referencePoint.Position = p1a;
                            //    referencePoint1.Position = p2a;
                            //    referencePoint2.Position = p3a;
                            //    referencePoint3.Position = p1b;
                            //    referencePoint4.Position = p2b;
                            //    referencePoint5.Position = p3b;

                            //}
                            //trans.Commit();




                            Solid solid = null;
                            ICollection<VertexPair> vp = new List<VertexPair>();
                            vp.Add(new VertexPair(0, 0));
                            vp.Add(new VertexPair(1, 1));
                            vp.Add(new VertexPair(2, 2));
                            try
                            {
                                solid = GeometryCreationUtilities.CreateBlendGeometry(cla, clb, vp);
                            }
                            catch
                            { }
                            if (solid != null)
                            {
                                solid_list.Add(solid);
                                point_six point_ = new point_six();
                                point_.p1 = p1a;
                                point_.p2 = p2a;
                                point_.p3 = p3a;
                                point_.p4 = p1b;
                                point_.p5 = p2b;
                                point_.p6 = p3b;
                                point_six_list.Add(point_);
                                kh1_list.Add(kh_list[i]);
                                kh2_list.Add(kh_list[t]);
                                kh3_list.Add(kh_list[r]);
                                delta_list.Add(delta);
                                int_list.Add(int_i_list[s]);
                                index1_list.Add(i);
                                index2_list.Add(t);
                                index3_list.Add(r);
                            }
                        }
                        #endregion

                    }

                    #region 材质相关
                    //材质集合
                    FilteredElementCollector m_collector = new FilteredElementCollector(doc);
                    ElementClassFilter m_typefilter = new ElementClassFilter(typeof(Material));
                    IList<Element> mtset = m_collector.WherePasses(m_typefilter).ToElements();
                    IList<string> mtnameset = new List<string>();
                    foreach (Element e in mtset)
                    {
                        mtnameset.Add(e.Name);
                    }

                    //做材质
                    for (int j = 0; j < name_list.Count; j++)
                    {
                        string str = name_list[j];
                        if (mtnameset.Contains(str))
                            continue;
                        Transaction transaction0 = new Transaction(doc, "yy");
                        FailureHandlingOptions failureHandlingOptions = transaction0.GetFailureHandlingOptions();
                        FailureHandler failureHandler = new FailureHandler();
                        failureHandlingOptions.SetFailuresPreprocessor(failureHandler);
                        failureHandlingOptions.SetClearAfterRollback(true);
                        transaction0.SetFailureHandlingOptions(failureHandlingOptions);
                        transaction0.Start();
                        Material m = creatematerial(doc, str, false);
                        Random RandomNum_First = new Random((int)DateTime.Now.Ticks);
                        System.Threading.Thread.Sleep(RandomNum_First.Next(50));
                        Random RandomNum_Sencond = new Random((int)DateTime.Now.Ticks);
                        int int_Red = RandomNum_First.Next(256);
                        int int_Green = RandomNum_Sencond.Next(256);
                        int int_Blue = (int_Red + int_Green > 400) ? 0 : 400 - int_Red - int_Green;
                        int_Blue = (int_Blue > 255) ? 255 : int_Blue;
                        m.Color = new Color((byte)int_Red, (byte)int_Green, (byte)int_Blue);
                        m.MaterialClass = "地质材质";
                        mtset.Add(m);
                        transaction0.Commit();
                    }

                    //新材质集合
                    FilteredElementCollector m_collector2 = new FilteredElementCollector(doc);
                    ElementClassFilter m_typefilter2 = new ElementClassFilter(typeof(Material));
                    IList<Element> mtset2 = m_collector2.WherePasses(m_typefilter2).ToElements();

                    int t1 = solid_list.Count;
                    string s1 = "{0} of " + t1.ToString();
                    //string caption1 = "做族";
                    string caption2 = "生成";

                    List<string> path_list = new List<string>();
                    #endregion

                    #region 生成常规模型族
                    using (FilterProgressForm prf1 = new FilterProgressForm(caption1, s1, t1))
                    {
                        for (int i = 0; i <= solid_list.Count - 1; i++)
                        {
                            //做族
                            string templateFileName = Revit.FamilyTemplatePath + "\\公制常规模型.rft";
                            Autodesk.Revit.DB.Document familydoc_gd = Revit.NewFamilyDocument(templateFileName);
                            Autodesk.Revit.Creation.FamilyItemFactory creationFamily_gd = familydoc_gd.FamilyCreate;
                            Transaction transactionff = new Transaction(familydoc_gd, "yy"); transactionff.Start();
                            FamilyParameter fp = familydoc_gd.FamilyManager.AddParameter("材质", BuiltInParameterGroup.PG_MATERIALS, ParameterType.Material, true);
                            Element e = FreeFormElement.Create(familydoc_gd, solid_list[i]);
                            familydoc_gd.FamilyManager.AssociateElementParameterToFamilyParameter(e.LookupParameter("材质"), fp);
                            transactionff.Commit();

                            string tmp_fName = tmppath;
                            tmp_fName += "\\地质" + layername_list[i] + "层_" + i + "_" + index1_list[i] + "_" + index2_list[i] + "_" + index3_list[i] + "_";
                            tmp_fName += int_list[i].ToString() + ".rfa";
                            try
                            {
                                familydoc_gd.SaveAs(tmp_fName);
                                path_list.Add(tmp_fName);
                            }
                            catch
                            { }
                            familydoc_gd.Close(false);
                            delfile_list.Add(tmp_fName);

                            //Transaction transaction23 = new Transaction(doc, "yy"); transaction23.Start();
                            //doc.LoadFamily(tmp_fName);


                            //string familyname = tmp_fName.Substring(tmp_fName.LastIndexOf("\\") + 1, tmp_fName.Length - tmp_fName.LastIndexOf("\\") - 5);
                            //IEnumerable<FamilySymbol> familysymbols = from elem in new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol))
                            //                                          let fstmp = elem as FamilySymbol
                            //                                          where fstmp.Name == familyname
                            //                                          select fstmp;
                            //FamilySymbol symbol = doc.GetElement(familysymbols.First().Id) as FamilySymbol;

                            ////Transaction transaction82 = new Transaction(doc, "yy"); transaction82.Start();
                            //symbol.Activate();
                            //transaction23.Commit();

                            if (prf1.progressBar1.Tag.ToString() == "Cancel")
                                break;
                            prf1.Increment();
                        }
                    }
                    #endregion

                    #region 放置常规模型族
                    using (FilterProgressForm prf1 = new FilterProgressForm(caption2, s1, t1))
                    {
                        //for (int i = 0; i <= 10; i++)


                        // Transaction transaction8 = new Transaction(doc, "yy"); transaction8.Start();
                        Family family = (new FilteredElementCollector(doc)
                         .OfCategory(BuiltInCategory.OST_GenericModel)
                         .OfClass(typeof(FamilySymbol)).Where(x => x.Name == "自适应地质块").First() as FamilySymbol).Family;

                        Autodesk.Revit.DB.Document fdoc = doc.EditFamily(family);
                        Transaction transs = new Transaction(fdoc);
                        transs.Start("faq");
                        if (null != fdoc)
                        {
                            FamilyManager fm = fdoc.FamilyManager;

                            for (int i = 0; i <= solid_list.Count - 1; i++)
                            {
                                string tmp_fName = string.Empty;
                                tmp_fName += "地质" + layername_list[i] + "层_" + i + "_" + index1_list[i] + "_" + index2_list[i] + "_" + index3_list[i] + "_";
                                tmp_fName += int_list[i].ToString();
                                try
                                {
                                    FamilyType ft = fm.NewType(tmp_fName);
                                }
                                catch (Exception)
                                {
                                }
                            }

                        }
                        transs.Commit();
                        LoadOpts loadOptions = new LoadOpts();
                        family = fdoc.LoadFamily(doc, loadOptions);


                        Transaction trans = new Transaction(doc);
                        trans.Start("11");
                        for (int i = 0; i <= solid_list.Count - 1; i++)
                        {
                            string tmp_fName = string.Empty;
                            tmp_fName += "地质" + layername_list[i] + "层_" + i + "_" + index1_list[i] + "_" + index2_list[i] + "_" + index3_list[i] + "_";
                            tmp_fName += int_list[i].ToString();
                            FamilySymbol symbol1 = new FilteredElementCollector(doc)
                        .OfCategory(BuiltInCategory.OST_GenericModel)
                        .OfClass(typeof(FamilySymbol)).Where(x => x.Name == tmp_fName).First() as FamilySymbol;




                            FamilyInstance familyInstance = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, symbol1);
                            IList<ElementId> plist = AdaptiveComponentInstanceUtils.GetInstancePointElementRefIds(familyInstance);
                            ReferencePoint referencePoint = doc.GetElement(plist.ElementAt(0)) as ReferencePoint;
                            ReferencePoint referencePoint1 = doc.GetElement(plist.ElementAt(1)) as ReferencePoint;
                            ReferencePoint referencePoint2 = doc.GetElement(plist.ElementAt(2)) as ReferencePoint;
                            ReferencePoint referencePoint3 = doc.GetElement(plist.ElementAt(3)) as ReferencePoint;
                            ReferencePoint referencePoint4 = doc.GetElement(plist.ElementAt(4)) as ReferencePoint;
                            ReferencePoint referencePoint5 = doc.GetElement(plist.ElementAt(5)) as ReferencePoint;
                            referencePoint.Position = point_six_list.ElementAt(i).p4;
                            referencePoint1.Position = point_six_list.ElementAt(i).p5;
                            referencePoint2.Position = point_six_list.ElementAt(i).p6;
                            referencePoint3.Position = point_six_list.ElementAt(i).p1;
                            referencePoint4.Position = point_six_list.ElementAt(i).p2;
                            referencePoint5.Position = point_six_list.ElementAt(i).p3;


                            foreach (Element me in mtset2)
                            {
                                if (me.Name == layername_list[i])
                                {
                                    familyInstance.LookupParameter("材质").Set(me.Id);
                                    break;
                                }
                            }









                            //string tmp_fName = tmppath;
                            //tmp_fName += "\\地质" + layername_list[i] + "层_" + i + "_" + index1_list[i] + "_" + index2_list[i] + "_" + index3_list[i] + "_";
                            //tmp_fName += int_list[i].ToString() + ".rfa";
                            //try
                            //{
                            //    doc.LoadFamily(tmp_fName);
                            //}
                            //catch
                            //{
                            //    prf1.Increment();
                            //    continue;
                            //}

                            //string familyname = tmp_fName.Substring(tmp_fName.LastIndexOf("\\") + 1, tmp_fName.Length - tmp_fName.LastIndexOf("\\") - 5);
                            //IEnumerable<FamilySymbol> familysymbols = from elem in new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol))
                            //                                          let fstmp = elem as FamilySymbol
                            //                                          where fstmp.Name == familyname
                            //                                          select fstmp;
                            //FamilySymbol symbol = doc.GetElement(familysymbols.First().Id) as FamilySymbol;
                            //symbol.Activate();




                            //FamilyInstance fi = doc.Create.NewFamilyInstance(delta_list[i], symbol, curview.GenLevel, StructuralType.NonStructural);

                            //Transaction transaction9 = new Transaction(doc, "yy"); transaction9.Start();
                            familyInstance.LookupParameter("注释").Set(layername_list[i]);
                            familyInstance.LookupParameter("孔号1").Set(kh1_list[i]);
                            familyInstance.LookupParameter("孔号2").Set(kh2_list[i]);
                            familyInstance.LookupParameter("孔号3").Set(kh3_list[i]);

                            //foreach (Element me in mtset2)
                            //{
                            //    if (me.Name == layername_list[i])
                            //    {
                            //        fi.LookupParameter("材质").Set(me.Id);
                            //        break;
                            //    }
                            //}
                            //transaction9.Commit();
                            if (prf1.progressBar1.Tag.ToString() == "Cancel")
                                break;
                            prf1.Increment();



                        }
                        trans.Commit();
                        //transaction8.Commit();
                    }
                    #endregion

                    ICollection<ElementId> categories = new List<ElementId>();
                    foreach (Category c in doc.Settings.Categories)
                    {
                        BuiltInCategory bic = (BuiltInCategory)c.Id.IntegerValue;
                        if (c.Name == "常规模型")
                            categories.Add(c.Id);
                    }


                    //加过滤器
                    for (int i = 0; i < name_list.Count; i++)
                    {
                        string str = name_list[i];

                        FilterRule fr = null;
                        try
                        {
                            fr = ParameterFilterRuleFactory.CreateEqualsRule(new ElementId(-1010106), str, true);
                        }
                        catch
                        {
                            continue;
                        }
                        List<FilterRule> fr_list = new List<FilterRule>();
                        fr_list.Add(fr);

                        Transaction transaction00 = new Transaction(doc, "yy");
                        transaction00.Start();
                        try
                        {
                            ParameterFilterElement pf = ParameterFilterElement.Create(doc, str, categories, fr_list);
                            //Random RandomNum_First = new Random((int)DateTime.Now.Ticks);
                            //System.Threading.Thread.Sleep(RandomNum_First.Next(50));
                            //Random RandomNum_Sencond = new Random((int)DateTime.Now.Ticks);
                            ////  为了在白色背景上显示，尽量生成深色
                            //int int_Red = RandomNum_First.Next(256);
                            //int int_Green = RandomNum_Sencond.Next(256);
                            //int int_Blue = (int_Red + int_Green > 400) ? 0 : 400 - int_Red - int_Green;
                            //int_Blue = (int_Blue > 255) ? 255 : int_Blue;

                            //OverrideGraphicSettings ogs = new OverrideGraphicSettings();
                            //ogs.SetProjectionLineColor(new Autodesk.Revit.DB.Color(0, 0, 0));
                            //ogs.SetProjectionLinePatternId(ElementId.InvalidElementId);
                            //ogs.SetProjectionFillColor(new Autodesk.Revit.DB.Color((byte)int_Red, (byte)int_Green, (byte)int_Blue));
                            //ogs.SetProjectionFillPatternId(solidid);
                            curview.AddFilter(pf.Id);
                            curview.SetFilterVisibility(pf.Id, true);
                            //curview.SetFilterOverrides(pf.Id, ogs);
                        }
                        catch
                        { }
                        transaction00.Commit();
                    }

                    Transaction transaction1 = new Transaction(doc, "yy"); transaction1.Start();
                    curview.DisplayStyle = DisplayStyle.ShadingWithEdges;
                    //doc.Delete(floor.Id);
                    transaction1.Commit();
                }
                excel.Quit();
                excel = null;
            }
            status = transGroup.Assimilate();
            foreach (string delpath in delfile_list)
            {
                System.IO.File.Delete(delpath);
            }
            return Result.Succeeded;
        }

        //求b点相对于a点的角度（从aX转到ab的角度），从0到360。
        public double ang_of_vector(XYZ a, XYZ b)
        {
            Double angle = 0;
            if (a.X == b.X)
            {
                if (a.Y > b.Y)
                    angle = 270;
                else
                    angle = 90;
            }
            if (a.Y == b.Y)
            {
                if (a.X > b.X)
                    angle = 180;
                else
                    angle = 0;
            }
            if (a.X != b.X && a.Y != b.Y)
            {
                double atan = Math.Atan((b.Y - a.Y) / (b.X - a.X)) * 180 / Math.PI;
                if (b.X > a.X && b.Y > a.Y)
                    angle = atan;
                if (b.X < a.X)
                    angle = atan + 180;
                if (b.X > a.X && b.Y < a.Y)
                    angle = atan + 360;
            }
            return angle;
        }

        //创建新材质
        public Material creatematerial(Autodesk.Revit.DB.Document doc, string name, Boolean stru)
        {
            Material material = null;
            try
            {
                ElementId materialId = Material.Create(doc, name);
                material = doc.GetElement(materialId) as Material;
                StructuralAsset strucAsset = new StructuralAsset("创筑", StructuralAssetClass.Undefined);
                strucAsset.Behavior = StructuralBehavior.Isotropic;
                PropertySetElement propertySet = PropertySetElement.Create(doc, strucAsset);
                propertySet.get_Parameter(BuiltInParameter.PROPERTY_SET_NAME).Set(name);
                propertySet.get_Parameter(BuiltInParameter.PHY_MATERIAL_PARAM_CLASS).Set((int)StructuralMaterialType.Undefined);
                propertySet.get_Parameter(BuiltInParameter.PHY_MATERIAL_PARAM_UNIT_WEIGHT).Set(232);
                material.SetMaterialAspectByPropertySet(Autodesk.Revit.DB.MaterialAspect.Structural, propertySet.Id);
            }
            catch
            { }
            return material;
        }

        //求点列中Z坐标最接近p的点的索引
        public int index_pz_nearest(List<XYZ> point_list, XYZ p)
        {
            double k = 100000;
            int t = -1;
            for (int i = 0; i < point_list.Count; i++)
            {
                XYZ pp = point_list[i];
                if (Math.Abs(pp.Z - p.Z) < k)
                {
                    k = Math.Abs(pp.Z - p.Z);
                    t = i;
                }
            }
            return t;
        }

        //求点列中p点的索引，容差tor
        public int index_pointinlist(List<XYZ> point_list, XYZ p, double tor)
        {
            int t = -1;
            for (int i = 0; i < point_list.Count; i++)
            {
                if (point_list[i].DistanceTo(p) < tor)
                {
                    t = i;
                }
            }
            return t;
        }

        //判断三点顺逆时针（仅考虑水平面）
        public int clockwise(XYZ p1, XYZ p2, XYZ p3)
        {
            int k = 1;
            double d = (p2.X - p1.X) * (p3.Y - p2.Y) - (p2.Y - p1.Y) * (p3.X - p2.X);
            if (Math.Abs(d) < 0.000001)
                k = 0;
            else if (d < 0)  //顺时针
                k = -1;
            return k;
        }
    }
    class LoadOpts : IFamilyLoadOptions
    {
        public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
        {
            overwriteParameterValues = true;
            return true;
        }
        public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
        {
            source = FamilySource.Family;
            overwriteParameterValues = true;
            return true;
        }
    }
    struct point_six
    {
        public XYZ p1, p2, p3, p4, p5, p6;
        public point_six(XYZ p1, XYZ p2, XYZ p3, XYZ p4, XYZ p5, XYZ p6)
        {
            this.p1 = p1;
            this.p2 = p2;
            this.p3 = p3;
            this.p4 = p4;
            this.p5 = p5;
            this.p6 = p6;
        }
    }

}
