using Autodesk.Revit.DB; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.UI; using System.Collections.Generic; using System.Linq; //using COME4Revit.WinForm; 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 DrawPipeRack : IExternalCommand { UIApplication uiapp; UIDocument uidoc; Autodesk.Revit.DB.Document doc; Autodesk.Revit.Creation.Application creApp; Autodesk.Revit.Creation.Document creDoc; public double m_MarginWidth = 0; 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; Level m_setLvlElem = null; int RadType = 0; PipeInfo pipeInfo1 = new PipeInfo(); PipeInfo pipeInfo2 = new PipeInfo(); try { //if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded; //파이프 선택 IList pickrefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, new PipeSelectionFilter(), "가대 설치할 배관 선택 : "); if (pickrefs.Count == 0) { MessageBox.Show("선택한 파이프가 없습니다.", "오류"); return Result.Cancelled; } //파이프로 변환 List PipeLst = new List(); foreach (Reference refer in pickrefs) { PipeLst.Add(doc.GetElement(refer) as Pipe); } //가장 큰 관경 구하기 Pipe MaxDiaPipe = getMaxPipe(PipeLst); //최소 관경 구하기 Pipe MinOffsetPipe = getMinOffsetPipe(PipeLst); //if(MinOffsetPipe!=null) //대화상자 Form_PipeRack dlg = new Form_PipeRack(); dlg.revit = commandData; dlg.MaxDiaPipe = MaxDiaPipe; dlg.MinOffPipe = MinOffsetPipe; dlg.ShowDialog(); if (dlg.DialogResult == DialogResult.Cancel) return Result.Cancelled; m_MarginWidth = dlg.m_MarginDist; //대화상자 선택한 레벨 가져오기 FilteredElementCollector lvlCollector = new FilteredElementCollector(doc); ICollection lvlCollection = lvlCollector.OfClass(typeof(Level)).ToElements(); foreach (Element elem in lvlCollection) { Level lvl = elem as Level; if (lvl.Name == dlg.m_LvlSet) m_setLvlElem = lvl; } // 23.06.07(JYH) 바닥 슬라브가 존재 할 경우 FilteredElementCollector floorcollector = new FilteredElementCollector(doc); ICollection flrIds = floorcollector.OfClass(typeof(Floor)).ToElementIds(); double flr_Height = 0.0; double selLvl_Height = 0.0; foreach (ElementId flrId in flrIds) { Floor floor = doc.GetElement(flrId) as Floor; if (floor.LevelId == m_setLvlElem.Id) { Parameter offsetParam = floor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM); double flr_offset = offsetParam.AsDouble(); flr_Height = flr_offset; selLvl_Height = m_setLvlElem.Elevation; MessageBox.Show(Unit.FeetToMM(flr_Height).ToString()); MessageBox.Show(Unit.FeetToMM(selLvl_Height).ToString()); break; } } //볼트 타입 RadType = dlg.m_Radidx; foreach (Pipe pp in PipeLst) { if (m_setLvlElem.Elevation > pp.ReferenceLevel.Elevation + pp.LevelOffset) { MessageBox.Show("배치 레벨과 파이프 간격이 좁습니다.", "오류"); return Result.Cancelled; } //파이프 리스트 중 높이가 좁을 경우 명령어 취소 if ((dlg.m_LvlCurrent != "Unknown" && dlg.m_LvlCurrent == dlg.m_LvlSet) || dlg.m_LvlCurrent == "Unknown") { if (pp.LevelOffset < Unit.MMToFeet(200)) { MessageBox.Show("배치 레벨과 파이프 간격이 좁습니다.", "오류"); return Result.Cancelled; } } } //가대 심볼 로드되어 있지 않으면 로드 FamilySymbol fs = LoadFamilys("Chanel_Support_lower.rfa", null); if (fs == null) fs = getNameByFamily("Chanel_Support_lower"); //U볼트 패밀리 로드 FamilySymbol bolt = LoadFamilys("U_bolt.rfa", null); if (bolt == null) bolt = getNameByFamily("U_bolt"); //가이드 슈 패밀리 로드 FamilySymbol shoe = LoadFamilys("Guide_Shoe.rfa", null); if (shoe == null) shoe = getNameByFamily("Guide_Shoe"); while (true) { //가대 위치 지정 Reference pickref = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new PipeSelectionFilter(), "가대 위치 지정 : "); //위치 포인트 XYZ insertPt = pickref.GlobalPoint; //위치포인트에서 양 쪽 가장 먼 파이프 두개를 찾아 교차점 구하기 //XYZ SideInterPt1 = null, SideInterPt2 = null; List pipeInfoLst = new List(); if (PipeLst.Count == 1) { pipeInfo1.pipe = doc.GetElement(pickref) as Pipe; Line line = (pipeInfo1.pipe.Location as LocationCurve).Curve as Line; IntersectionResult interRes = line.Project(insertPt); pipeInfo1.InterPt = interRes.XYZPoint; pipeInfoLst.Add(pipeInfo1); } else { pipeInfoLst = getSidePipe(PipeLst, insertPt, ref pipeInfo1, ref pipeInfo2); } //Util.Pyosi(doc,SideInterPt1,1); //MessageBox.Show("1"); //심볼이 로드되지 않으면 실행 X if (fs != null) { using (Transaction trans = new Transaction(doc)) { trans.Start("symbol"); if (fs.IsActive == false) fs.Activate(); if (bolt.IsActive == false) bolt.Activate(); if (shoe.IsActive == false) shoe.Activate(); Pipe firstPipe = doc.GetElement(pickrefs.First()) as Pipe; XYZ sp = null, ep = null; Util.GetStartEndPoint(firstPipe, ref sp, ref ep); XYZ PipeVec = (ep - sp).Normalize(); XYZ RotVec = Util.RotateVector(PipeVec, Util.DTR(90)); FamilyInstance family = null; FamilyInstance TypeFamily = null; List boltFamLst = new List(); //파이프 1개 선택 시 if (pipeInfo2.pipe == null) { XYZ tmp = new XYZ(0, 0, 0); //가대 설치 //family = doc.Create.NewFamilyInstance(pipeInfo1.InterPt, fs, RotVec, doc.GetElement(pickref), StructuralType.NonStructural); family = doc.Create.NewFamilyInstance(pipeInfo1.InterPt, fs, RotVec, doc.GetElement(pickref), StructuralType.NonStructural); if (RadType == 0) { //파이프가 1개일 때 가이드 슈 TypeFamily = doc.Create.NewFamilyInstance(pipeInfo1.InterPt, shoe, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural); pipeInfoLst.First().family = TypeFamily; } else if (RadType == 1) { //파이프가 1개일 때 U볼트 TypeFamily = doc.Create.NewFamilyInstance(pipeInfo1.InterPt, bolt, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural); pipeInfoLst.First().family = TypeFamily; } //Util.Pyosi(doc, pipeInfo1.InterPt, 0); } else { //파이프 여러개 선택 시 양 끝 파이프 센터점에 가대 설치 XYZ centerPt = Util.Polar(pipeInfo1.InterPt, pipeInfo1.InterPt, pipeInfo2.InterPt, pipeInfo1.InterPt.DistanceTo(pipeInfo2.InterPt) / 2.0); family = doc.Create.NewFamilyInstance(centerPt, fs, RotVec, doc.GetElement(pickref), StructuralType.NonStructural); //Util.Pyosi(doc, centerPt, 0); //U볼트 가이드 슈 삽입 foreach (PipeInfo info in pipeInfoLst) { XYZ locPt = new XYZ(info.InterPt.X, info.InterPt.Y, info.pipe.ReferenceLevel.Elevation + info.pipe.LevelOffset); if (RadType == 0) { TypeFamily = doc.Create.NewFamilyInstance(locPt, shoe, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural); info.family = TypeFamily; doc.Regenerate(); List conLst = Util.GetElementConnectors(TypeFamily); Connector shoeCon = conLst.First(); //Util.Pyosi(doc, pipeInfo1.InterPt, 0); doc.Regenerate(); //가이드 슈 커넥터 위치를 기준으로 파이프 중심으로 이동 XYZ translation = locPt - shoeCon.Origin; ElementTransformUtils.MoveElement(doc, TypeFamily.Id, translation); } else if (RadType == 1) { TypeFamily = doc.Create.NewFamilyInstance(locPt, bolt, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural); info.family = TypeFamily; } } } doc.Regenerate(); //패밀리 옵션 설정 FamilyOption(family, pipeInfoLst, pipeInfo1, pipeInfo2, PipeLst, m_setLvlElem, RadType, flr_Height, selLvl_Height); trans.Commit(); } } else break; }//while end } catch (Exception e) { //MessageBox.Show("" + e); } return Result.Succeeded; } //패밀리 옵션 설정 private void FamilyOption(FamilyInstance Rack, List pipeInfoLst, PipeInfo pipeInfo1, PipeInfo pipeInfo2, List pipeLst, Level SelectLevel, int BoltType, double flr_Height, double selLvl_Height) { //////////////////////////////가대 설정//////////////////////////////////// Definition df = null; double MaxPipeOutDia = 0; double MinOffPipeOutDia = 0; //가장 큰 관경 구하기 Pipe MaxDiaPipe = getMaxPipe(pipeLst); //가장 큰 관경 외경 Parameter maxOutDiaParam = MaxDiaPipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER); if (maxOutDiaParam != null) MaxPipeOutDia = maxOutDiaParam.AsDouble(); //오프셋 값이 가장 높은 값. Pipe MinOffsetPipe = getMinOffsetPipe(pipeLst); //파이프 단열제 두께 double MaxinsulThk = 0, MininsulThk = 0; if (MinOffsetPipe != null) { MininsulThk = Util.GetPipeInsulationThickness(doc, MinOffsetPipe); Parameter minOutDiaParam = MinOffsetPipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER); if (minOutDiaParam != null) MinOffPipeOutDia = minOutDiaParam.AsDouble(); } else MaxinsulThk = Util.GetPipeInsulationThickness(doc, MaxDiaPipe); //가대 설정 if (Rack != null) { //가대 채널 on df = GetDefinition(Rack, "First_Chanel"); if (df != null) { Parameter paramChanel = Rack.get_Parameter(df); if (paramChanel != null) paramChanel.Set(1); } //가대 폭 df = GetDefinition(Rack, "Support_Width"); if (df != null) { Parameter paramWidth = Rack.get_Parameter(df); if (paramWidth != null) { if (pipeInfo2.pipe == null) { double sidePipeDia = pipeInfo1.pipe.Diameter; //파이프 관경 + 여유분(100) paramWidth.Set(sidePipeDia + Unit.MMToFeet(m_MarginWidth)); } else { double sidePipeDia = pipeInfo1.pipe.Diameter; double side2PipeDia = pipeInfo2.pipe.Diameter; //양 쪽 사이드 파이프 관경 + 양 사이드 파이프 거리 + 여유분(100) paramWidth.Set(sidePipeDia + side2PipeDia + pipeInfo1.InterPt.DistanceTo(pipeInfo2.InterPt) + Unit.MMToFeet(m_MarginWidth)); } } } //간격 띄우기 값 구하기 double m_Offset = 0; Parameter paramOffset = Rack.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM); if (paramOffset != null) { m_Offset = paramOffset.AsDouble(); if (MinOffsetPipe == null) m_Offset = MaxDiaPipe.LevelOffset;//모든 파이프 offset 같다 = 관경 가장 큰 파이프 offset else m_Offset = MinOffsetPipe.LevelOffset;//모든 파이프 offset 같지 X = offset 가장 낮은 파이프의 offset //가장 큰 관경만큼 간격띄우기 조정 if (MinOffsetPipe != null) { //paramOffset.Set(MinOffsetPipe.LevelOffset - MinOffsetPipe.Diameter / 2.0 - MininsulThk + MinOffsetPipe.ReferenceLevel.Elevation); paramOffset.Set(MinOffsetPipe.LevelOffset - MinOffPipeOutDia / 2.0 - MininsulThk + MinOffsetPipe.ReferenceLevel.Elevation - flr_Height); } else { //paramOffset.Set(MaxDiaPipe.LevelOffset - MaxDiaPipe.Diameter / 2.0 - MaxinsulThk + MaxDiaPipe.ReferenceLevel.Elevation); paramOffset.Set(MaxDiaPipe.LevelOffset - MaxDiaPipe.Diameter / 2.0 - MaxinsulThk + MaxDiaPipe.ReferenceLevel.Elevation - flr_Height); } } doc.Regenerate(); //다리 길이1 df = GetDefinition(Rack, "Support_Height1"); if (df != null) { Parameter paramLeg1 = Rack.get_Parameter(df); if (paramLeg1 != null) { //가대 변경된 offset 값과 같음. paramOffset = Rack.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM); //현재 뷰의 레벨만큼 빼서 다리길이 조정(대화상자 만든다면 제거할것) //MinOffsetPipe의 offset - MinOffsetPipe 반지름 - 배치레벨높이 if (MinOffsetPipe != null) { paramLeg1.Set(m_Offset - MinOffPipeOutDia / 2.0 - MininsulThk + (MinOffsetPipe.ReferenceLevel.Elevation - SelectLevel.Elevation)); //paramLeg1.Set(m_Offset - MinOffsetPipe.Diameter / 2.0 - MininsulThk + (MinOffsetPipe.ReferenceLevel.Elevation - SelectLevel.Elevation)); } else { paramLeg1.Set(m_Offset - MaxPipeOutDia / 2.0 - MaxinsulThk + (MaxDiaPipe.ReferenceLevel.Elevation - SelectLevel.Elevation)); //paramLeg1.Set(m_Offset - MaxDiaPipe.Diameter / 2.0 - MaxinsulThk + (MaxDiaPipe.ReferenceLevel.Elevation - SelectLevel.Elevation)); } } } //doc.Regenerate(); //다리 길이2 df = GetDefinition(Rack, "Support_Height2"); if (df != null) { Parameter paramLeg2 = Rack.get_Parameter(df); if (paramLeg2 != null) { //현재 뷰의 레벨만큼 빼서 다리길이 조정(대화상자 만든다면 제거할것) //MinOffsetPipe의 offset - MinOffsetPipe 반지름 - 배치레벨높이 if (MinOffsetPipe != null) { paramLeg2.Set(m_Offset - MinOffPipeOutDia / 2.0 - MininsulThk + (MinOffsetPipe.ReferenceLevel.Elevation - SelectLevel.Elevation)); //paramLeg2.Set(m_Offset - MinOffsetPipe.Diameter / 2.0 - MininsulThk + (MinOffsetPipe.ReferenceLevel.Elevation - SelectLevel.Elevation)); } else { paramLeg2.Set(m_Offset - MaxPipeOutDia / 2.0 - MaxinsulThk + (MaxDiaPipe.ReferenceLevel.Elevation - SelectLevel.Elevation)); //paramLeg2.Set(m_Offset - MaxDiaPipe.Diameter / 2.0 - MaxinsulThk + (MaxDiaPipe.ReferenceLevel.Elevation - SelectLevel.Elevation)); } } } } double m_CoverThk = 0, m_plateHgt = 0, m_plateThk = 0; //////////////////////////////U볼트 가이드슈 설정//////////////////////////////////// foreach (PipeInfo info in pipeInfoLst) { //파이프 단열제 두께 double insulThk = Util.GetPipeInsulationThickness(doc, info.pipe); //파이프 외경 Parameter param = info.pipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER); double m_CurPipeOutDia = 0; if (param != null) m_CurPipeOutDia = param.AsDouble(); //가이드 슈 if (BoltType == 0)//가이드 슈 { if (info.family != null) { //관경(외경) 변경 df = GetDefinition(info.family, "GuideShoeCoverInRad"); if (df != null) { Parameter paramSteelDia = info.family.get_Parameter(df); if (paramSteelDia != null) paramSteelDia.Set(m_CurPipeOutDia / 2.0 + insulThk); //paramSteelDia.Set(info.pipe.Diameter / 2.0 + insulThk); } //커넥터 관경 변경 df = GetDefinition(info.family, "ConRad"); if (df != null) { Parameter paramConRad = info.family.get_Parameter(df); if (paramConRad != null) paramConRad.Set(m_CurPipeOutDia / 2.0 + insulThk); //paramConRad.Set(info.pipe.Diameter / 2.0 + insulThk); } //슈 폭 변경 df = GetDefinition(info.family, "HalfGuideShoeCoverWidth"); if (df != null) { Parameter paramSteelHalfWidth = info.family.get_Parameter(df); if (paramSteelHalfWidth != null) paramSteelHalfWidth.Set(Unit.MMToFeet(25)); } df = GetDefinition(info.family, "GuideShoeCoverGap"); if (df != null) { Parameter paramCoverGap = info.family.get_Parameter(df); if (paramCoverGap != null) paramCoverGap.Set(Unit.MMToFeet(3)); } //가대 높이 재설정 //가이드 슈 두께 df = GetDefinition(info.family, "GuideShoeCoverThk"); if (df != null) { Parameter paramCoverThk = info.family.get_Parameter(df); if (paramCoverThk != null) { paramCoverThk.Set(Unit.MMToFeet(5));//default value = 5 } } doc.Regenerate(); df = GetDefinition(info.family, "GuideShoeCoverThk"); if (df != null) { Parameter paramCoverThk = info.family.get_Parameter(df); if (paramCoverThk != null) m_CoverThk = paramCoverThk.AsDouble(); } //판 두께 df = GetDefinition(info.family, "SupportThk"); if (df != null) { Parameter paramPlateThk = info.family.get_Parameter(df); if (paramPlateThk != null) m_plateThk = paramPlateThk.AsDouble(); } //판 높이 df = GetDefinition(info.family, "SupportHeight"); if (df != null) { Parameter paramPlateHgt = info.family.get_Parameter(df); if (paramPlateHgt != null) { m_plateHgt = paramPlateHgt.AsDouble(); if (MinOffsetPipe != null) { //판높이 + (MinOffsetPipe 반지름 - 현재 파이프 반지름) + (현재 파이프offset - MinOffsetPipe의offset) paramPlateHgt.Set(m_plateHgt + ((MinOffPipeOutDia / 2.0 + MininsulThk) - (m_CurPipeOutDia / 2.0 + insulThk)) + (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset)); //paramPlateHgt.Set(m_plateHgt + ((MinOffsetPipe.Diameter / 2.0 + MininsulThk) - (info.pipe.Diameter / 2.0 + insulThk)) //+ (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset)); } else { //판높이 +(MaxDiaPipe반지름 - 현재파이프 반지름) paramPlateHgt.Set(m_plateHgt + ((MaxPipeOutDia / 2.0 + MaxinsulThk) - (m_CurPipeOutDia / 2.0 + insulThk)) ); //paramPlateHgt.Set(m_plateHgt + ((MaxDiaPipe.Diameter / 2.0 + MaxinsulThk) - (info.pipe.Diameter / 2.0 + insulThk))); } } } } } else if (BoltType == 1)//U볼트 { //U볼트 패밀리 설정 if (info.family != null) { //간격 띄우기 값 구하기 double m_Offset = 0; Parameter paramOffset = info.family.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM); if (paramOffset != null) { m_Offset = paramOffset.AsDouble(); //가장 큰 관경만큼 간격띄우기 조정 if (MinOffsetPipe != null) paramOffset.Set(m_Offset - MinOffPipeOutDia / 2.0 - MininsulThk - (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset)); else paramOffset.Set(m_Offset - MaxPipeOutDia / 2.0 - MaxinsulThk); } //관경 변경 df = GetDefinition(info.family, "Diameter"); if (df != null) { Parameter paramDia = info.family.get_Parameter(df); if (paramDia != null) { paramDia.Set(info.pipe.Diameter + insulThk * 2); } } //외경 변경 df = GetDefinition(info.family, "OutDiameter"); if (df != null) { Parameter paramOutDia = info.family.get_Parameter(df); if (paramOutDia != null) { Parameter p_outDia = info.pipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER); if(MinOffsetPipe!=null) paramOutDia.Set(p_outDia.AsDouble() + MininsulThk * 2); else paramOutDia.Set(p_outDia.AsDouble() + MaxinsulThk * 2); } } double boltDia = 0; double mm_PipeDia = Unit.FeetToMM(info.pipe.Diameter + insulThk * 2); if (mm_PipeDia >= 15 && mm_PipeDia <= 50) boltDia = Unit.MMToFeet(10); else if (mm_PipeDia >= 65 && mm_PipeDia <= 90) boltDia = Unit.MMToFeet(12); else if (mm_PipeDia > 90 && mm_PipeDia <= 175) boltDia = Unit.MMToFeet(16); else if (mm_PipeDia > 175 && mm_PipeDia <= 250) boltDia = Unit.MMToFeet(20); else if (mm_PipeDia > 250 && mm_PipeDia <= 400) boltDia = Unit.MMToFeet(24); else if (mm_PipeDia > 400 && mm_PipeDia <= 500) boltDia = Unit.MMToFeet(30); else if (mm_PipeDia > 500) boltDia = Unit.MMToFeet(32); else boltDia = Unit.MMToFeet(8); df = GetDefinition(info.family, "Bolt_Diameter"); if (df != null) { Parameter paramBoltDia = info.family.get_Parameter(df); if (paramBoltDia != null) paramBoltDia.Set(boltDia); } //높이 지정 df = GetDefinition(info.family, "Support_Height"); if (df != null) { Parameter paramSupportHgt = info.family.get_Parameter(df); if (paramSupportHgt != null) { if (MinOffsetPipe != null) { paramSupportHgt.Set(MinOffPipeOutDia / 2.0 + MininsulThk + (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset)); } else paramSupportHgt.Set(MaxPipeOutDia / 2.0 + MaxinsulThk); } } doc.Regenerate(); } } } // //가이드 슈 일 경우 가대 높이, 다리길이 재조정 if (BoltType == 0) { doc.Regenerate(); //가대간격 띄우기 값 구하기 Parameter paramOffset = Rack.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM); double m_Offset = 0; if (paramOffset != null) { m_Offset = paramOffset.AsDouble(); //가장 큰 관경만큼 간격띄우기 조정 paramOffset.Set(m_Offset - (m_CoverThk + m_plateThk + m_plateHgt)); } df = GetDefinition(Rack, "Support_Height1"); if (df != null) { Parameter paramLeg1 = Rack.get_Parameter(df); if (paramLeg1 != null) { double supLength = paramLeg1.AsDouble(); paramLeg1.Set(supLength - (m_CoverThk + m_plateThk + m_plateHgt)); } } df = GetDefinition(Rack, "Support_Height2"); if (df != null) { Parameter paramLeg2 = Rack.get_Parameter(df); if (paramLeg2 != null) { double supLength = paramLeg2.AsDouble(); paramLeg2.Set(supLength - (m_CoverThk + m_plateThk + m_plateHgt)); } } } } /// /// 관경이 가장 큰 파이프 구하기 /// /// 파이프 리스트 /// private Pipe getMaxPipe(List pipeLst) { double MaxDia = 0; Pipe MaxPipe = null; foreach (Pipe pp in pipeLst) { double m_PipeDia = pp.Diameter; //단열재 두께 double insulThk = Util.GetPipeInsulationThickness(doc, pp); if (MaxDia < m_PipeDia + insulThk) { MaxDia = m_PipeDia + (insulThk * 2); MaxPipe = pp; } } return MaxPipe; } private Pipe getMinOffsetPipe(List pipeLst) { double MinOffset = double.MaxValue; Pipe MinOffsetPipe = null; bool b_other = false; //파이프 간격띄우기 값이 다 같으면 null 리턴 foreach (Pipe pp in pipeLst) { if (pipeLst.First().LevelOffset != pp.LevelOffset) { b_other = true; break; } } //파이프 간격띄우기 값이 다른게 있다면 실행 if (b_other) { foreach (Pipe pp in pipeLst) { double pipeOffset = pp.LevelOffset; if (MinOffset > pipeOffset) { MinOffset = pipeOffset; MinOffsetPipe = pp; } } } return MinOffsetPipe; } /// /// 기준점에서 가장 먼 파이프 구하기 /// /// 파이프 리스트 /// 기준점 /// 기준점과 파이프 교차점 /// private List getSidePipe(List pipeList, XYZ DirPt, ref PipeInfo sideInfo1, ref PipeInfo sideInfo2) { double minDist = double.MaxValue; double maxDist = 0; List PipeInfoLst = new List(); foreach (Pipe pipe in pipeList) { Line line = (pipe.Location as LocationCurve).Curve as Line; IntersectionResult interRes = line.Project(DirPt); XYZ interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, 0); PipeInfo info = new PipeInfo(); info.pipe = pipe; info.InterPt = interPt; PipeInfoLst.Add(info); } XYZ vec = (PipeInfoLst.First().InterPt - PipeInfoLst.Last().InterPt).Normalize(); XYZ virtualPt = Util.Polar(PipeInfoLst.First().InterPt, vec, Unit.MMToFeet(10000)); foreach (PipeInfo pipeInfo in PipeInfoLst) { if (maxDist < virtualPt.DistanceTo(pipeInfo.InterPt)) { sideInfo1 = pipeInfo; maxDist = virtualPt.DistanceTo(pipeInfo.InterPt); } if (minDist > virtualPt.DistanceTo(pipeInfo.InterPt)) { sideInfo2 = pipeInfo; minDist = virtualPt.DistanceTo(pipeInfo.InterPt); } } //Util.Pyosi(doc, sideInfo1.InterPt, 1); //MessageBox.Show("1"); //Util.Pyosi(doc, sideInfo2.InterPt, 1); //MessageBox.Show("2"); return PipeInfoLst; } // 패밀리 존재 여부 검토 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; } 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\\PipeRack"); // 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; } 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; } public class PipeSelectionFilter : ISelectionFilter { public bool AllowElement(Element element) { if (element.Category == null) return false; if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeCurves) { return true; } return false; } public bool AllowReference(Reference refer, XYZ point) { return false; } } } }