[Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class cmdDuctWall : IExternalCommand { public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elements) { UIApplication uiApp = cmdData.Application; UIDocument uiDoc = cmdData.Application.ActiveUIDocument; Document doc = uiDoc.Document; Selection sel = uiDoc.Selection; Transaction ts = new Transaction(uiDoc.Document, " delete "); ts.Start(); // 加载链接文件 FilteredElementCollector collector = new FilteredElementCollector(doc); // collector.OfClass( typeof(Instance)).OfCategory(BuiltInCategory.OST_RvtLinks); // RevitLinkType List< string> listPath = GetLinkFilePaths(doc); Duct duct = doc.GetElement(sel.PickObject(ObjectType.Element, " duct ")) as Duct; foreach (Element elDoc in collector) { Instance ins = elDoc as Instance; if (ins != null) { Transform transForm = ins.GetTransform(); string strKey = elDoc.Name.Substring( 0, elDoc.Name.IndexOf( " .rvt ")); // 找到链接文件名称 string strPath = GetLinkPath(listPath, strKey); Document docLink = uiApp.Application.OpenDocumentFile(strPath); List<Wall> listWall = FindDuctWall(doc, duct, docLink, ins.GetTransform().Origin); TaskDialog.Show( " count ", listWall.Count.ToString()); List<Wall> listWall1 = FindDuctWall(doc, duct); TaskDialog.Show( " count ", listWall1.Count.ToString()); } } ts.Commit(); return Result.Succeeded; } /// <summary> /// 找到当前文档穿过的墙 /// </summary> /// <param name="doc"></param> /// <param name="duct"></param> /// <returns></returns> public List<Wall> FindDuctWall(Document doc, Duct duct) { List<Wall> listWall = new List<Wall>(); // 找到outLine BoundingBoxXYZ bb = duct.get_BoundingBox(doc.ActiveView); Outline outline = new Outline(bb.Min, bb.Max); // WinFormTools.MsgBox(bb.Min + "|" + bb.Max); // FilteredElementCollector collector = new FilteredElementCollector(doc); BoundingBoxIntersectsFilter invertFilter = new BoundingBoxIntersectsFilter(outline, false); IList<Element> noIntersectWalls = collector.OfClass( typeof(Wall)).WherePasses(invertFilter).ToElements(); foreach (Element el in noIntersectWalls) { Wall wall = el as Wall; if (wall != null) listWall.Add(wall); } return listWall; } /// <summary> /// 找到穿过链接文件的墙 /// </summary> /// <param name="doc"></param> /// <param name="duct"></param> /// <param name="docLink"></param> /// <param name="xyz"> 依稀量 </param> /// <returns></returns> public List<Wall> FindDuctWall(Document doc, Duct duct, Document docLink, XYZ xyz) { List<Wall> listWall = new List<Wall>(); // 找到outLine BoundingBoxXYZ bb = duct.get_BoundingBox(doc.ActiveView); Outline outline = new Outline(bb.Min - xyz, bb.Max - xyz); // FilteredElementCollector collector = new FilteredElementCollector(docLink); BoundingBoxIntersectsFilter invertFilter = new BoundingBoxIntersectsFilter(outline, false); IList<Element> noIntersectWalls = collector.OfClass( typeof(Wall)).WherePasses(invertFilter).ToElements(); foreach (Element el in noIntersectWalls) { Wall wall = el as Wall; if (wall != null) listWall.Add(wall); } return listWall; } /// <summary> /// 取得链接文件路径 /// </summary> /// <param name="doc"></param> /// <returns></returns> public List< string> GetLinkFilePaths(Document doc) { List< string> listPath = new List< string>(); foreach (ElementId elId in ExternalFileUtils.GetAllExternalFileReferences(doc)) { if (doc.get_Element(elId).IsExternalFileReference()) { ExternalFileReference fileRef = doc.get_Element(elId).GetExternalFileReference(); if (ExternalFileReferenceType.RevitLink == fileRef.ExternalFileReferenceType) listPath.Add(ModelPathUtils.ConvertModelPathToUserVisiblePath(fileRef.GetAbsolutePath())); } } return listPath; } /// <summary> /// 根据链接文件名称找到对应链接路径,模糊匹配,待改进 /// </summary> /// <param name="listPath"></param> /// <param name="strKey"></param> /// <returns></returns> public string GetLinkPath(List< string> listPath, string strKey) { foreach ( string strPath in listPath) { if (strPath.Contains(strKey)) return strPath; } return ""; } }