using System; using System.IO; using System.Linq; using System.Text; using System.Data; using System.Collections; using System.Windows.Forms; 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.DB.Structure; using System.Collections.Generic; using System.Runtime.InteropServices; using uBIM_EarthTools; using TriangleNet; namespace uBIM_EarthTools { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] class GeologyCylinder : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; 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.Cancelled; List boreholeList = ExcelHelper.GetDataFromExcel(pathstring); List typesList = ExcelHelper.GetGeologyType(pathstring).Select(x => "地质" + x.Key + "-" + x.Value + "层").ToList(); TransactionStatus status = TransactionStatus.Uninitialized; TransactionGroup transGroup = new TransactionGroup(doc, "地质钻孔圆柱建模"); if (transGroup.Start() == TransactionStatus.Started) { Transaction transaction = new Transaction(doc); FailureHandlingOptions failureHandlingOptions = transaction.GetFailureHandlingOptions(); FailureHandler failureHandler = new FailureHandler(); failureHandlingOptions.SetFailuresPreprocessor(failureHandler); failureHandlingOptions.SetClearAfterRollback(true); transaction.SetFailureHandlingOptions(failureHandlingOptions); #region 加载族,创建族类型 IEnumerable familys = new FilteredElementCollector(doc) .OfCategory(BuiltInCategory.OST_GenericModel) .OfClass(typeof(FamilySymbol)).Where(x => x.Name == "地质钻孔圆柱"); if (!familys.Any()) { transaction.Start("Load Family"); byte[] bit = uBIM_EarthTools.Resource.地质钻孔圆柱 as byte[]; string filepath = AppConfig.APP_TEMP_PATH + "\\地质钻孔圆柱.rfa"; File.WriteAllBytes(filepath, bit); doc.LoadFamily(filepath); File.Delete(filepath); transaction.Commit(); } 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 trans = new Transaction(fdoc); trans.Start("Create FamilySymbol"); if (null != fdoc) { FamilyManager fm = fdoc.FamilyManager; foreach (string type in typesList) { try { FamilyType ft = fm.NewType(type); } catch { } } } trans.Commit(); LoadOpts loadOptions = new LoadOpts(); family = fdoc.LoadFamily(doc, loadOptions); #endregion #region 材质 IList mtset = new FilteredElementCollector(doc) .WherePasses(new ElementClassFilter(typeof(Material))).ToElements(); transaction.Start("Create Material"); foreach (string Type in typesList) { if (mtset.Select(x => x.Name).ToList().Contains(Type)) continue; else { Material material = CreateMaterial(doc, Type, false); Random randomNumFirst = new Random((int)DateTime.Now.Ticks); System.Threading.Thread.Sleep(randomNumFirst.Next(50)); Random randomNumSencond = new Random((int)DateTime.Now.Ticks); int intRed = randomNumFirst.Next(256); int intGreen = randomNumSencond.Next(256); int intBlue = (intRed + intGreen > 400) ? 0 : 400 - intRed - intGreen; intBlue = (intBlue > 255) ? 255 : intBlue; material.Color = new Color((byte)intRed, (byte)intGreen, (byte)intBlue); material.MaterialClass = "地质材质"; mtset.Add(material); } } transaction.Commit(); #endregion int count = 0; boreholeList.ForEach(x => count += x.ValueList.Count); #region 生成族实例 using (FilterProgressForm prf1 = new FilterProgressForm("生成", "{0} of " + count.ToString(), count)) { transaction.Start("Create FamilyInstance"); foreach (Borehole borehole in boreholeList) { for (int i = 1; i < borehole.ValueList.Count; i++) { GeologyLayer geologyLayer = borehole.ValueList[i]; FamilySymbol familySymbol = new FilteredElementCollector(doc) .OfCategory(BuiltInCategory.OST_GenericModel).OfClass(typeof(FamilySymbol)) .First(x => x.Name == geologyLayer.Type) as FamilySymbol; if (!familySymbol.IsActive) { familySymbol.Activate(); } FamilyInstance familyInstance = doc.Create.NewFamilyInstance(geologyLayer.Point, familySymbol, StructuralType.NonStructural); familyInstance.LookupParameter("深度") .Set(borehole.ValueList[i - 1].Point.Z - geologyLayer.Point.Z); familyInstance.LookupParameter("材质") .Set(mtset.First(x => x.Name == familyInstance.Name).Id); familyInstance.LookupParameter("孔号").Set(borehole.Name); if (prf1.progressBar1.Tag.ToString() == "Cancel") break; prf1.Increment(); System.Windows.Forms.Application.DoEvents(); } } } transaction.Commit(); #endregion } status = transGroup.Assimilate(); return Result.Succeeded; } 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("uBIM", 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; } } }