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.UI.Selection;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB.Structure;

namespace EarthLayerModel
{
    [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 = 19;
            int y_column = 18;
            int z_column = 2;    //“孔口标高”
            int begin_row = 3;   //从第几行开始是正式坐标数据。从1算起。            
            MessageBox.Show("当前Z坐标使用孔口绝对坐标。" + "\n" + "OK", "向日葵", MessageBoxButtons.OK);

            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

                string pathstring = "";
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Title = "选择Excel文件…";
                openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);//桌面路径     //注意这里写路径时要用c:\\而不是c:\
                openFileDialog.Filter = "文本文件|*.xls";
                openFileDialog.RestoreDirectory = true;
                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
                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*50;
                    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坐标不同
                    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;
                            try
                            {
                                x = double.Parse((ws.Cells[m, x_column]).Text) * 1000 / 304.8;
                                y = double.Parse((ws.Cells[m, y_column]).Text) * 1000 / 304.8;
                                double z = double.Parse((ws.Cells[m, z_column]).Text) * 1000 / 304.8;
                                point_list.Add(new XYZ(x, y, z));
                                newpoint_list.Add(new XYZ(x, y, z));
                            }
                            catch
                            {
                                MessageBox.Show(m + "\n" + (ws.Cells[m, x_column]).Text + "\n" + (ws.Cells[m, y_column]).Text + "\n" + (ws.Cells[m, z_column]).Text, "向日葵", MessageBoxButtons.OK);
                                continue;
                            }
                            
                            //第i个string对应第i个点与第i+1个点
                            for (int n = z_column + 1; n < Math.Min(x_column,y_column); n++)
                            {
                                if (ws.Cells[m, n].Text != "")
                                {
                                    if (!name_list.Contains(ws.Cells[m, n].Text))
                                        name_list.Add(ws.Cells[m, n].Text);
                                    newstring_list.Add(ws.Cells[m, n].Text);                                    
                                    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(new XYZ(x, y, zp));
                                    }
                                    catch
                                    {
                                        MessageBox.Show(m + "\n" + (ws.Cells[m + 1, n]).Text, "向日葵", MessageBoxButtons.OK);
                                    }
                                }
                            }
                            str_list_list.Add(newstring_list);
                            point_list_list.Add(newpoint_list);
                            kh_list.Add(ws.Cells[m, 1].Text);
                        }
                    }
                    //求包络外框                    
                    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 transaction = new Transaction(doc, "yy"); transaction.Start();
                    Floor floor = doc.Create.NewFloor(ca, true);
                    transaction.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);
                    }  

                    //求三角面
                    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) > 50000 / 304.8)   //大于50米不考虑连接
                                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) > 50000 / 304.8 || p30.DistanceTo(p20) > 50000 / 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，互相连接
                                    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];

                                    //string stri = "";
                                    //foreach (string s in str_i)
                                    //    stri += s + "_";
                                    //string strt = "";
                                    //foreach (string s in str_t)
                                    //    strt += s + "_";
                                    //string strr = "";
                                    //foreach (string s in str_r)
                                    //    strr += s + "_";
                                    //MessageBox.Show(str_i.Count + "\n" + str_t.Count + "\n" + str_r.Count, "向日葵", MessageBoxButtons.OK);
                                    //MessageBox.Show(stri + "\n" + strt + "\n" + strr, "向日葵", MessageBoxButtons.OK);

                                    Boolean ok = false;
                                    do
                                    {
                                        ok = true;
                                        int mincount = Math.Min(Math.Min(str_i.Count, str_t.Count), str_r.Count);
                                        for (int x = 0; x <= mincount - 1; x++)
                                        {
                                            if (str_i[x] == str_t[x] && str_i[x] != str_r[x])
                                            {
                                                str_r.Insert(x, str_t[x]);
                                                xyz_r.Insert(x, xyz_r[x]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            if (str_i[x] != str_t[x] && str_i[x] == str_r[x])
                                            {
                                                str_t.Insert(x, str_i[x]);
                                                xyz_t.Insert(x, xyz_t[x]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            if (str_i[x] != str_t[x] && str_t[x] == str_r[x])
                                            {
                                                str_i.Insert(x, str_r[x]);
                                                xyz_i.Insert(x, xyz_i[x]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            if (str_i[x] != str_t[x] && str_t[x] != str_r[x] && str_i[x] != str_r[x])
                                            {
                                                str_t.Insert(x, str_i[x]);
                                                xyz_t.Insert(x, xyz_t[x]);  //重复上一点
                                                str_r.Insert(x, str_i[x]);
                                                xyz_r.Insert(x, xyz_r[x]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            //最后补齐三列数据使其等长
                                            if (str_i.Count == x+1 && str_t.Count > x+1)
                                            {
                                                str_i.Add(str_t[x + 1]);
                                                xyz_i.Add(xyz_i[x + 1]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            if (str_i.Count == x+1 && str_r.Count > x+1)
                                            {
                                                str_i.Add(str_r[x + 1]);
                                                xyz_i.Add(xyz_i[x + 1]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            if (str_t.Count == x+1 && str_i.Count > x+1)
                                            {
                                                str_t.Add(str_i[x + 1]);
                                                xyz_t.Add(xyz_t[x + 1]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            if (str_t.Count == x+1 && str_r.Count > x+1)
                                            {
                                                str_t.Add(str_r[x + 1]);
                                                xyz_t.Add(xyz_t[x + 1]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            if (str_r.Count == x+1 && str_t.Count > x+1)
                                            {
                                                str_r.Add(str_t[x + 1]);
                                                xyz_r.Add(xyz_r[x + 1]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }
                                            if (str_r.Count == x+1 && str_i.Count > x+1)
                                            {
                                                str_r.Add(str_i[x + 1]);
                                                xyz_r.Add(xyz_r[x + 1]);  //重复上一点
                                                ok = false;
                                                continue;
                                            }

                                        }
                                    }
                                    while (ok == false);

                                    //string stri2 = "";
                                    //foreach (string s in str_i)
                                    //    stri2 += s + "_";
                                    //string strt2 = "";
                                    //foreach (string s in str_t)
                                    //    strt2 += s + "_";
                                    //string strr2 = "";
                                    //foreach (string s in str_r)
                                    //    strr2 += s + "_";
                                    //MessageBox.Show(stri2 + "\n" + strt2 + "\n" + strr2, "向日葵", MessageBoxButtons.OK);

                                    //string xyzi2 = "";
                                    //foreach (XYZ p in xyz_i)
                                    //    xyzi2 += p.Z*304.8 + "_";
                                    //string xyzt2 = "";
                                    //foreach (XYZ p in xyz_t)
                                    //    xyzt2 += p.Z * 304.8 + "_";
                                    //string xyzr2 = "";
                                    //foreach (XYZ p in xyz_r)
                                    //    xyzr2 += p.Z * 304.8 + "_";

                                    //MessageBox.Show(xyzi2 + "\n" + xyzt2 + "\n" + xyzr2, "向日葵", MessageBoxButtons.OK);

                                    
                                    List<int> int_i = new List<int>();   //记录已生成的段落
                                    List<int> int_t = new List<int>();
                                    List<int> int_r = new List<int>();

                                    if (str_i.Count < 2)
                                        continue;
                                    for (int si = 0; si <= str_i.Count - 1; si++)
                                    {
                                        XYZ delta = xyz_i[si];
                                        XYZ p1a = xyz_i[si] - delta;
                                        XYZ p2a = xyz_t[si] - delta;
                                        XYZ p3a = xyz_r[si] - delta;
                                        XYZ p1b = xyz_i[si + 1] - delta;
                                        XYZ p2b = xyz_t[si + 1] - delta;
                                        XYZ p3b = xyz_r[si + 1] - delta;

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

                                        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);                                        

                                        Solid solid = null;
                                        try
                                        {
                                            solid = GeometryCreationUtilities.CreateBlendGeometry(cla, clb, null);
                                        }
                                        catch
                                        { }
                                        if (solid == null)
                                            continue;

                                        //做族
                                        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();
                                        Element e = FreeFormElement.Create(familydoc_gd, solid);
                                        transactionff.Commit();

                                        string tmp_fName = tmppath;
                                        tmp_fName += "\\地质" + str_i[si] + "层_" + kh_list[i] + "_" + kh_list[t] + "_" + kh_list[r] + "_";
                                        tmp_fName += si.ToString() + ".rfa";
                                        try
                                        {
                                            familydoc_gd.SaveAs(tmp_fName);
                                        }
                                        catch
                                        { }
                                        familydoc_gd.Close(false);
                                        delfile_list.Add(tmp_fName);

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

                                        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();
                                        transaction82.Commit();

                                        Transaction transaction8 = new Transaction(doc, "yy"); transaction8.Start();
                                        FamilyInstance fi = doc.Create.NewFamilyInstance(delta, symbol, curview.GenLevel, StructuralType.NonStructural);
                                        transaction8.Commit();
                                        Transaction transaction9 = new Transaction(doc, "yy"); transaction9.Start();
                                        fi.LookupParameter("注释").Set(str_i[si]);
                                        fi.LookupParameter("孔号1").Set(kh_list[i]);
                                        fi.LookupParameter("孔号2").Set(kh_list[t]);
                                        fi.LookupParameter("孔号3").Set(kh_list[r]);
                                        transaction9.Commit(); 
                                    }
                                }
                            }
                        } 
                    }

                    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;
                    transaction1.Commit();

                }
                excel.Quit();
                excel = null;                
            }
            status = transGroup.Assimilate();
            foreach (string delpath in delfile_list)
            {
                System.IO.File.Delete(delpath);
            }
            return Result.Succeeded;
        }
        //public 
    }

    public class FailureHandler : IFailuresPreprocessor
    {
        public string ErrorMessage { set; get; }
        public string ErrorSeverity { set; get; }

        public FailureHandler()
        {
            ErrorMessage = "";
            ErrorSeverity = "";
        }

        public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
        {
            IList<FailureMessageAccessor> failureMessages = failuresAccessor.GetFailureMessages();
            foreach (FailureMessageAccessor failureMessageAccessor in failureMessages)
            {
                FailureDefinitionId id = failureMessageAccessor.GetFailureDefinitionId();
                try
                {
                    ErrorMessage = failureMessageAccessor.GetDescriptionText();
                }
                catch
                {
                    ErrorMessage = "Unknown Error";
                }

                try
                {
                    FailureSeverity failureSeverity = failureMessageAccessor.GetSeverity();
                    ErrorSeverity = failureSeverity.ToString();
                    if (failureSeverity == FailureSeverity.Warning)
                    {
                        failuresAccessor.DeleteWarning(failureMessageAccessor);

                    }
                    else
                    {
                        failuresAccessor.ResolveFailure(failureMessageAccessor);
                        return FailureProcessingResult.ProceedWithCommit;
                    }
                }
                catch
                { }
            }
            return FailureProcessingResult.Continue;
        }
    }
}
