using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Creation; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using KDCS.Utils; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using View = Autodesk.Revit.DB.View; namespace KMBIM { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class AssemTest : IExternalCommand { UIApplication uiapp; UIDocument uidoc; Autodesk.Revit.DB.Document doc; Autodesk.Revit.Creation.Application creApp; Autodesk.Revit.Creation.Document creDoc; Autodesk.Revit.UI.ExternalCommandData m_commandData; public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { m_commandData = commandData; uiapp = commandData.Application; uidoc = uiapp.ActiveUIDocument; doc = uidoc.Document; creApp = uiapp.Application.Create; creDoc = doc.Create; try { //어셈블리 부착할 파이프 선택 Reference pickRef = commandData.Application.ActiveUIDocument.Selection.PickObject(ObjectType.Element); Element elem = doc.GetElement(pickRef); LanguageType lang = commandData.Application.Application.Language; View view = doc.ActiveView; if (elem is Pipe) { List fam1 = new List(); if (lang == LanguageType.English_USA || lang == LanguageType.English_GB) fam1 = getFamily("Pipe Accessories"); else if (lang == LanguageType.Korean) fam1 = getFamily("파이프 액세서리"); FamilySymbol valve = null; FamilySymbol straigner = null; using (Transaction trans = new Transaction(doc)) { trans.Start("1"); //나비형 밸브 로드 valve = getFamilySymbol(fam1, "C:\\ProgramData\\DCS.CO.KR\\KMBIM\\Libraries\\Header\\family\\2019\\KS_Butterfly Valve -Lever.rfa"); //스트레이너 로드 straigner = getFamilySymbol(fam1, "C:\\ProgramData\\Autodesk\\RVT 2019\\Libraries\\Korea\\배관\\액세서리\\M_Y 스트레이너 - 50-500mm - 플랜지.rfa"); //나비형 밸브 설치 후 배관과 연결 FamilyInstance valveFam = insertFamilyAndConnectPipe(pickRef.GlobalPoint, elem as Pipe, valve); //배관 생성 CreatePipeFromFamily(elem as Pipe, valveFam, Unit.MMToFeet(200)); // trans.Commit(); } } } catch (Exception e) { MessageBox.Show("" + e); } return Result.Succeeded; } private Pipe CreatePipeFromFamily(Pipe MainPipe,FamilyInstance Family,double PipeDist) { //선택 배관 ElementId pickPipeTypeId = MainPipe.PipeType.Id; ElementId pickPipeSystemTypeId = MainPipe.MEPSystem.GetTypeId(); ElementId pickPipeLevelId = MainPipe.ReferenceLevel.Id; //밸브 커넥터 List valveConLst = Util.GetElementConnectors(Family); Connector DisConnectCon = null, ConnectCon = null; //연결되지 않은 커넥터 구하기 foreach (Connector con in valveConLst) { if (con.IsConnected == false) DisConnectCon = con; else ConnectCon = con; } //배관 그릴 점 리스트 List PipePtLst = new List(); PipePtLst.Add(DisConnectCon.Origin); //연결 안 된 커넥터쪽 방향 XYZ vec = (DisConnectCon.Origin - ConnectCon.Origin).Normalize(); XYZ plrPt = Util.Polar(DisConnectCon.Origin, vec, Unit.MMToFeet(200)); PipePtLst.Add(plrPt); List createPipeLst = Util.CreatePipe(uiapp, doc, PipePtLst, pickPipeSystemTypeId, pickPipeTypeId, pickPipeLevelId); Pipe NewPipe = null; if(createPipeLst.Count>0) NewPipe = createPipeLst.First(); if (NewPipe != null) { Parameter paramDia = NewPipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM); if (paramDia != null) paramDia.Set(MainPipe.Diameter); } return NewPipe; } private FamilyInstance insertFamilyAndConnectPipe(XYZ PickPt, Pipe InsertPipe, FamilySymbol Symbol) { Connector spCon = null, epCon = null; FamilyInstance valveFam = null; try { Util.GetStartEndConnector(InsertPipe, ref spCon, ref epCon); Line PipeLine = (InsertPipe.Location as LocationCurve).Curve as Line; IntersectionResult interRes = PipeLine.Project(PickPt); XYZ PipeVec = (epCon.Origin - spCon.Origin).Normalize(); XYZ ClosePt = interRes.XYZPoint; //밸브 배치할 커넥터 Connector SetCon = null, SetOtherCon = null; if (ClosePt.DistanceTo(spCon.Origin) > ClosePt.DistanceTo(epCon.Origin)) { SetCon = epCon; SetOtherCon = spCon; } else { SetCon = spCon; SetOtherCon = epCon; } XYZ SetVec = (SetCon.Origin - SetOtherCon.Origin).Normalize(); XYZ SetOtherVec = (SetOtherCon.Origin - SetCon.Origin).Normalize(); //패밀리 삽입 valveFam = uidoc.Document.Create.NewFamilyInstance(SetCon.Origin, Symbol, PipeVec, InsertPipe, StructuralType.NonStructural); doc.Regenerate(); Parameter paramDia = valveFam.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM); if (paramDia != null) paramDia.Set(InsertPipe.Diameter); List FamConLst = Util.GetElementConnectors(valveFam); XYZ FamInsertPt = (valveFam.Location as LocationPoint).Point; // Connector valSpCon = null, valEpCon = null; foreach (Connector con in FamConLst) { XYZ vec = (con.Origin - FamInsertPt).Normalize(); if (vec.IsAlmostEqualTo(SetVec)) valEpCon = con; else valSpCon = con; } //SetCon.Origin = Util.Polar(SetCon.Origin, SetVec, valveInsertPt.DistanceTo(SetCon.Origin)); //커넥터 위치 옳김. SetCon.Origin = Util.Polar(SetCon.Origin, SetOtherVec, valEpCon.Origin.DistanceTo(SetCon.Origin)); doc.Regenerate(); //선택 파이프 끝 커넥터와 밸브 연결 SetCon.ConnectTo(valSpCon); } catch { } return valveFam; } private FamilySymbol getFamilySymbol(List FamSymbolLst, string symbolPath) { FamilySymbol symbol = null; if (FamSymbolLst.Count == 0) { string str = symbolPath; symbol = LoadFamilys(str); if (symbol == null) symbol = getNameByFamily(Path.GetFileNameWithoutExtension(str)); else { if (symbol.IsActive == false) symbol.Activate(); } } else if (FamSymbolLst.Count > 0) { string str = symbolPath; symbol = LoadFamilys(str); if (symbol == null) symbol = getNameByFamily(Path.GetFileNameWithoutExtension(str)); else { if (symbol.IsActive == false) symbol.Activate(); } } return symbol; } // 패밀리 존재 여부 검토 private List getFamily(string categori) { List familySymbol = new List(); List fiCreationDatas = new List(); ElementSet elementSet = null; //Try to get a FamilySymbol FilteredElementCollector collector = new FilteredElementCollector(m_commandData.Application.ActiveUIDocument.Document); ICollection collection = collector.OfClass(typeof(FamilySymbol)).ToElements(); FamilySymbol Symbol; foreach (Element e in collection) { Symbol = e as FamilySymbol; if (null != Symbol.Category) { if (categori == Symbol.Category.Name) { familySymbol.Add(Symbol); } } } return familySymbol; } private FamilySymbol LoadFamilys(string FamilyPath) { // get the active view's level for beam creation Level level = uidoc.Document.GetElement(uidoc.ActiveView.LevelId) as Level; // load a family symbol from file FamilySymbol gotSymbol = null; String fileName = FamilyPath;// "\\data\\2010-0240312-글로브_밸브_(플랜지형).rfa"; // 패밀리를 로드한다. Family fam = null; bool sw = uidoc.Document.LoadFamily(fileName, out fam); if (sw == true) { ISet fam_ids = fam.GetFamilySymbolIds(); List fam_sym_names = new List(); if (fam_ids.Count() == 0) return null; gotSymbol = (FamilySymbol)doc.GetElement(fam_ids.ElementAt(0)); } return gotSymbol; } // 패밀리 존재 여부 검토 private FamilySymbol getNameByFamily(string name) { List fiCreationDatas = new List(); ElementSet elementSet = null; //Try to get a FamilySymbol FilteredElementCollector collector = new FilteredElementCollector(m_commandData.Application.ActiveUIDocument.Document); ICollection collection = collector.OfClass(typeof(FamilySymbol)).ToElements(); FamilySymbol Symbol; FamilySymbol target = null; foreach (Element e in collection) { Symbol = e as FamilySymbol; if (null != Symbol.Category) { if (name == Symbol.Family.Name) { // MessageBox.Show(Symbol.Family.Name); target = Symbol; break; } } } return target; } } }