using Autodesk.Revit.DB; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.UI; using System.Collections.Generic; using System.Linq; using System.Diagnostics; using Autodesk.Revit.UI.Selection; using System; using System.Windows.Forms; using KDCS.Utils; using View = Autodesk.Revit.DB.View; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.Creation; using KMBIM.Revit.Tools; namespace KMBIM { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class bracingTest : IExternalCommand { UIApplication uiapp; UIDocument uidoc; Autodesk.Revit.DB.Document doc; Autodesk.Revit.Creation.Application creApp; Autodesk.Revit.Creation.Document creDoc; public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { uiapp = commandData.Application; uidoc = uiapp.ActiveUIDocument; Autodesk.Revit.ApplicationServices.Application app = uiapp.Application; doc = uidoc.Document; creApp = uiapp.Application.Create; creDoc = doc.Create; View view = doc.ActiveView; try { //버팀대 패밀리 로드 FamilySymbol bracing = LoadFamilys("횡방향버팀대.rfa", null); if (bracing == null) bracing = getNameByFamily("횡방향버팀대"); Reference PipeRef = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "볼트 설치할 배관 선택 : "); Pipe pickPipe = doc.GetElement(PipeRef) as Pipe; Curve PipeCur = ((pickPipe.Location) as LocationCurve).Curve; IntersectionResult interRes = PipeCur.Project(PipeRef.GlobalPoint); XYZ insertPt = interRes.XYZPoint; XYZ PipePt = insertPt; XYZ PipeSp = null, PipeEp = null; Util.GetStartEndPoint(pickPipe, ref PipeSp, ref PipeEp); //파이프 방향 XYZ DirVec = (PipeEp - PipeSp).Normalize(); XYZ rDirVec = (PipeSp - PipeEp).Normalize(); //Z값 기준 XYZ VecZ = XYZ.BasisZ; using (Transaction trans = new Transaction(doc)) { trans.Start("process"); bracing.Activate(); //레벨 배치 프로세스 bool b_tf = LevelProcess(PipeRef, "레벨 1", bracing, pickPipe); trans.Commit(); } } catch { } return Result.Succeeded; } //배치기준 레벨 public bool LevelProcess(Reference PipeRef, string setLevelName, FamilySymbol bracing,Pipe PipeHost) { bool b_TF = true; FamilyInstance family = null; IntersectionResult interRes = new IntersectionResult(); Pipe PickPipe = doc.GetElement(PipeRef) as Pipe; Curve PipeCur = (PickPipe.Location as LocationCurve).Curve; interRes = PipeCur.Project(PipeRef.GlobalPoint); //선택 파이프 점으로 파이프 중심점 구하기 XYZ insertPt = interRes.XYZPoint; XYZ PipePt = insertPt; XYZ PipeSp = null, PipeEp = null; Util.GetStartEndPoint(PickPipe, ref PipeSp, ref PipeEp); //레벨 찾기 Level m_SetLevel = Util.GetLevel(doc, setLevelName); //if (m_SetLevel.Elevation - PickPipe.ReferenceLevel.Elevation - PickPipe.LevelOffset < 0) //{ // MessageBox.Show("배치기준 레벨보다 파이프가 더 높이 있습니다.", "오류"); // return b_TF = false; //} //참조평면 생성 XYZ p2 = new XYZ(insertPt.X + Unit.MMToFeet(10), insertPt.Y, insertPt.Z); XYZ p1 = new XYZ(insertPt.X, insertPt.Y, insertPt.Z); XYZ p3 = new XYZ(insertPt.X, insertPt.Y + Unit.MMToFeet(10), insertPt.Z); ReferencePlane referPlane = doc.Create.NewReferencePlane2(p3, p1, p2, doc.ActiveView); //doc.Create.NewReferencePlane() family = doc.Create.NewFamilyInstance(referPlane.GetReference(), insertPt, (PipeEp - PipeSp).Normalize(), bracing); //family = doc.Create.NewFamilyInstance(insertPt,bracing, (PipeEp - PipeSp).Normalize(),PipeHost as Pipe,StructuralType.NonStructural); //family.IsWorkPlaneFlipped = false; doc.Regenerate(); //패밀리 옵션 SetFamilyOpt(family, PickPipe, m_SetLevel); //SetLevelBoltOpt(family, BoltType, PickPipe, m_SetLevel); return b_TF; } //패밀리 옵션 private void SetFamilyOpt(FamilyInstance bracing, Pipe pickPipe, Level setLevel) { Definition df = null; //파이프 단열제 두께 double insulThk = Util.GetPipeInsulationThickness(doc, pickPipe); //배관 반지름 df = GetDefinition(bracing, "BCoverInRad"); if (df != null) { Parameter paramCoverRad = bracing.get_Parameter(df); if (paramCoverRad != null) paramCoverRad.Set(pickPipe.Diameter / 2.0 + insulThk); } //배관 각도 df = GetDefinition(bracing, "PipeAngle"); if (df != null) { Parameter paramPipeAngle = bracing.get_Parameter(df); if (paramPipeAngle != null) paramPipeAngle.Set(Util.DTR(45)); } //버팀대 길이 df = GetDefinition(bracing, "Totaldist"); if (df != null) { Parameter paramTdist = bracing.get_Parameter(df); if (paramTdist != null) paramTdist.Set(Unit.MMToFeet(1000)); } } static Definition GetDefinition(Element elem, string parameter_name) { IList ps = elem.GetParameters(parameter_name); int n = ps.Count; Debug.Assert(1 >= n, "expected maximum one shared parameters" + "named " + parameter_name); Definition d = (0 == n) ? null : ps[0].Definition; return d; } private FamilySymbol LoadFamilys(string famroot, string famname) { string versionNumber = doc.Application.VersionNumber.ToString(); //string Tmp = System.Reflection.Assembly.GetExecutingAssembly().Location; //Tmp = Tmp.Replace("\\KMBIM2019.dll", ""); string Tmp = Util.GetKMBIMLibraryFolder("Libraries\\Bracing"); // get the active view's level for beam creation Level level = doc.GetElement(doc.ActiveView.LevelId) as Level; // load a family symbol from file FamilySymbol gotSymbol = null; String fileName = Tmp + "\\" + versionNumber + "\\" + famroot; // 아래의 이름은 패밀리 고유의 이름이다. 패밀리 작업할때 입력하게 되어있다. String name = famname; // 패밀리를 로드한다. Family fam = null; //m_document.Document.LoadFamilySymbol(fileName, "", out gotSymbol); bool sw = false; using (Transaction trans = new Transaction(doc)) { trans.Start("LoadFamily"); sw = doc.LoadFamily(fileName, out fam); trans.Commit(); } 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(); //Try to get a FamilySymbol FilteredElementCollector collector = new FilteredElementCollector(doc); 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; } } }