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 { public class LevelComparer : IComparer { public int Compare(Level a, Level b) { double diff = a.Elevation - b.Elevation; if (Math.Abs(diff) < 0.0001) return 0; else if (diff > 0.0001) return 1; else if (diff < 0.0001) return -1; else return 0; } } [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class DrawUpperPipeRack : 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; 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); Form_UpperPipeRack dlg = new Form_UpperPipeRack(); dlg.revit = commandData; dlg.MaxDiaPipe = MaxDiaPipe; dlg.MinOffPipe = MinOffsetPipe; dlg.ShowDialog(); if (dlg.DialogResult == DialogResult.Cancel) return Result.Cancelled; //대화상자 선택한 레벨 가져오기 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_LvlAttach) m_setLvlElem = lvl; } //볼트 타입 RadType = dlg.m_Radidx; foreach (Pipe pipe in PipeLst) { if (m_setLvlElem.Elevation < pipe.ReferenceLevel.Elevation + pipe.LevelOffset) { MessageBox.Show("파이프가 지지대 배치 레벨과 파이프 사이가 좁습니다..", "오류"); return Result.Cancelled; } if (pipe.ReferenceLevel.Name == m_setLvlElem.Name) { MessageBox.Show("파이프 참조 레벨과 지지대 부착 레벨이 같습니다.", "오류"); return Result.Cancelled; } } Level setLevel = Util.GetLevel(doc, dlg.m_LvlAttach); Level CurLevel = null; if (dlg.m_LvlCurrent == "Unknown") CurLevel = Util.GetLevel(doc, dlg.m_LvlCurrent); //가대 심볼 로드되어 있지 않으면 로드 FamilySymbol fs = Util.LoadFamilys(doc, "Chanel_Support_upper.rfa", "PipeRack"); if (fs == null) fs = Util.getNameByFamily(doc, "Chanel_Support_upper"); //U볼트 패밀리 로드 FamilySymbol bolt = Util.LoadFamilys(doc, "U_bolt.rfa", "PipeRack"); if (bolt == null) bolt = Util.getNameByFamily(doc, "U_bolt"); //가이드 슈 패밀리 로드 FamilySymbol shoe = Util.LoadFamilys(doc, "Guide_Shoe.rfa", "PipeRack"); if (shoe == null) shoe = Util.getNameByFamily(doc, "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); } //심볼이 로드되지 않으면 실행 X if (fs == null) break; 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(); XYZ sp = null, ep = null; Util.GetStartEndPoint(PipeLst.First(), ref sp, ref ep); XYZ PipeVec = (ep - sp).Normalize(); XYZ RotVec = Util.RotateVector(PipeVec, Util.DTR(90)); FamilyInstance Rack = null; FamilyInstance TypeFamily = null; //파이프 1개 선택 시 if (PipeLst.Count == 1) { XYZ locPt = null; if (MinOffsetPipe != null) locPt = new XYZ(pipeInfo1.InterPt.X, pipeInfo1.InterPt.Y, MinOffsetPipe.LevelOffset + MinOffsetPipe.ReferenceLevel.Elevation); else locPt = new XYZ(pipeInfo1.InterPt.X, pipeInfo1.InterPt.Y, MaxDiaPipe.LevelOffset + MaxDiaPipe.ReferenceLevel.Elevation); //가대 설치 Rack = doc.Create.NewFamilyInstance(locPt, fs, RotVec, doc.GetElement(pickref), StructuralType.NonStructural); if (RadType == 0) { //파이프가 1개일 때 가이드 슈 TypeFamily = doc.Create.NewFamilyInstance(locPt, shoe, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural); pipeInfoLst.First().family = TypeFamily; } else if (RadType == 1) { //파이프가 1개일 때 U볼트 TypeFamily = doc.Create.NewFamilyInstance(locPt, bolt, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural); pipeInfoLst.First().family = TypeFamily; } } else { //파이프 여러개 선택 시 양 끝 파이프 센터점에 가대 설치 XYZ centerPt = Util.Polar(pipeInfo1.InterPt, pipeInfo1.InterPt, pipeInfo2.InterPt, pipeInfo1.InterPt.DistanceTo(pipeInfo2.InterPt) / 2.0); if (MinOffsetPipe != null) centerPt = new XYZ(centerPt.X, centerPt.Y, MinOffsetPipe.LevelOffset + MinOffsetPipe.ReferenceLevel.Elevation); else centerPt = new XYZ(centerPt.X, centerPt.Y, MaxDiaPipe.LevelOffset + MaxDiaPipe.ReferenceLevel.Elevation); //SelectLevel.Elevation - MinOffsetPipe.LevelOffset - MinOffsetPipe.ReferenceLevel.Elevation + (MinOffsetPipe.Diameter / 2) + Unit.MMToFeet(150) Rack = doc.Create.NewFamilyInstance(centerPt, fs, RotVec, doc.GetElement(pickref), StructuralType.NonStructural); //Util.Pyosi(doc, centerPt, 0); //U볼트 가이드 슈 삽입 foreach (PipeInfo info in pipeInfoLst) { XYZ locPt = null; //locPt = new XYZ(info.InterPt.X, info.InterPt.Y, info.pipe.LevelOffset + MinOffsetPipe.ReferenceLevel.Elevation); if (RadType == 0) { if (MinOffsetPipe != null) locPt = new XYZ(info.InterPt.X, info.InterPt.Y, info.pipe.LevelOffset + MinOffsetPipe.ReferenceLevel.Elevation); else locPt = new XYZ(info.InterPt.X, info.InterPt.Y, info.pipe.LevelOffset + MaxDiaPipe.ReferenceLevel.Elevation); 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; //Util.Pyosi(doc, locPt, 0); //ElementTransformUtils.MoveElement(doc, TypeFamily.Id, translation); } else if (RadType == 1) { if (MinOffsetPipe != null) locPt = new XYZ(info.InterPt.X, info.InterPt.Y, MinOffsetPipe.LevelOffset + MinOffsetPipe.ReferenceLevel.Elevation); else locPt = new XYZ(info.InterPt.X, info.InterPt.Y, MaxDiaPipe.LevelOffset + MaxDiaPipe.ReferenceLevel.Elevation); TypeFamily = doc.Create.NewFamilyInstance(locPt, bolt, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural); info.family = TypeFamily; } } } //패밀리 옵션 설정 FamilyOption(Rack, pipeInfoLst, pipeInfo1, pipeInfo2, PipeLst, setLevel, RadType); //BoltOption(Rack, pipeInfoLst, setLevel, RadType); trans.Commit(); } }//while end } catch (Exception e) { } return Result.Succeeded; } //가대 옵션 설정 private void FamilyOption(FamilyInstance Rack, List pipeInfoLst, PipeInfo pipeInfo1, PipeInfo pipeInfo2, List pipeLst, Level SelectLevel, int BoltType) { //////////////////////////////가대 설정//////////////////////////////////// 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) return; //지지대 다리 off시 on으로 df = GetDefinition(Rack, "Support1"); if (df != null) { Parameter paramSupport1 = Rack.get_Parameter(df); if (paramSupport1 != null) paramSupport1.Set(1); } df = GetDefinition(Rack, "Support2"); if (df != null) { Parameter paramSupport2 = Rack.get_Parameter(df); if (paramSupport2 != null) paramSupport2.Set(1); } //2단 off df = GetDefinition(Rack, "2nd_Chanel"); if (df != null) { Parameter param2ndChanel = Rack.get_Parameter(df); if (param2ndChanel != null) param2ndChanel.Set(0); } 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; //파이프 관경 + 여유분(500) paramWidth.Set(sidePipeDia + Unit.MMToFeet(500)); } else { double sidePipeDia = pipeInfo1.pipe.Diameter; double side2PipeDia = pipeInfo2.pipe.Diameter; //양 쪽 사이드 파이프 관경 + 양 사이드 파이프 거리 + 여유분(500) paramWidth.Set(sidePipeDia + side2PipeDia + pipeInfo1.InterPt.DistanceTo(pipeInfo2.InterPt) + Unit.MMToFeet(500)); } } } //간격 띄우기 값 구하기 U볼트에만 적용 if (BoltType == 1 || BoltType == 2) { double m_Offset = 0, m_pipeDia = 0; ; Parameter paramOffset = Rack.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM); if (paramOffset != null) { m_Offset = paramOffset.AsDouble(); if (MinOffsetPipe == null) m_pipeDia = MaxPipeOutDia + MaxinsulThk * 2; else m_pipeDia = MinOffPipeOutDia + MininsulThk * 2; paramOffset.Set(m_Offset - m_pipeDia / 2.0); } } doc.Regenerate(); // //다리 길이1 df = GetDefinition(Rack, "Support_Length"); if (df != null) { Parameter paramLeg1 = Rack.get_Parameter(df); if (paramLeg1 != null) { //현재 뷰의 레벨만큼 빼서 다리길이 조정(대화상자 만든다면 제거할것) //paramLeg1.Set(m_Offset - MaxPipeDia / 2.0 - view.GenLevel.Elevation); if (MinOffsetPipe != null) { paramLeg1.Set(SelectLevel.Elevation - MinOffsetPipe.ReferenceLevel.Elevation - MinOffsetPipe.LevelOffset +Unit.MMToFeet(150) + MininsulThk + MinOffPipeOutDia / 2.0); //paramLeg1.Set(SelectLevel.Elevation - MinOffsetPipe.ReferenceLevel.Elevation - MinOffsetPipe.LevelOffset + Unit.MMToFeet(150) + MininsulThk + MinOffsetPipe.Diameter / 2.0); } else { paramLeg1.Set(SelectLevel.Elevation - MaxDiaPipe.ReferenceLevel.Elevation - MaxDiaPipe.LevelOffset + Unit.MMToFeet(150) + MaxinsulThk + MaxPipeOutDia / 2.0); //paramLeg1.Set(SelectLevel.Elevation - MaxDiaPipe.ReferenceLevel.Elevation - MaxDiaPipe.LevelOffset + Unit.MMToFeet(150) + MaxinsulThk + MaxDiaPipe.Diameter / 2.0); } } } //////////////////////////////U-볼트 가이드 슈 설정//////////////////////////////////// double m_CoverThk = 0, m_plateHgt = 0; 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) continue; //관경(외경) 변경 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) { paramCoverThk = info.family.get_Parameter(df); if (paramCoverThk != null) { m_CoverThk = paramCoverThk.AsDouble(); } } } //받침대 두께 df = GetDefinition(info.family, "SupportThk"); if (df != null) { Parameter paramSupThk = info.family.get_Parameter(df); if (paramSupThk != null) paramSupThk.Set(m_CoverThk); } //판 높이 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) { //paramPlateHgt.Set(m_plateHgt //+ (MinOffsetPipe.Diameter / 2.0 - info.pipe.Diameter / 2.0) //+ (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset) - insulThk); paramPlateHgt.Set(m_plateHgt + (MinOffPipeOutDia / 2.0 - m_CurPipeOutDia / 2.0) + (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset) + (MininsulThk - insulThk)); //paramPlateHgt.Set(m_plateHgt //+ (MinOffsetPipe.Diameter / 2.0 - info.pipe.Diameter / 2.0) //+ (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset) //+ (MininsulThk - insulThk)); } else { //paramPlateHgt.Set(m_plateHgt + (MaxDiaPipe.Diameter / 2.0 - info.pipe.Diameter / 2.0) - insulThk); paramPlateHgt.Set(m_plateHgt + (MaxPipeOutDia / 2.0 - m_CurPipeOutDia / 2.0) + (MaxinsulThk - insulThk)); //paramPlateHgt.Set(m_plateHgt + (MaxDiaPipe.Diameter / 2.0 - info.pipe.Diameter / 2.0) + (MaxinsulThk - insulThk)); } } } } else//U-볼트 { if (info.family == null) continue; //관경 변경 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); 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 >= 100 && mm_PipeDia <= 175) boltDia = Unit.MMToFeet(16); else if (mm_PipeDia >= 200 && mm_PipeDia <= 250) boltDia = Unit.MMToFeet(20); else if (mm_PipeDia >= 300 && mm_PipeDia <= 400) boltDia = Unit.MMToFeet(24); else if (mm_PipeDia >= 450 && mm_PipeDia <= 500) boltDia = Unit.MMToFeet(30); 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(); //간격 띄우기 값 구하기 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); else paramOffset.Set(m_Offset - MaxPipeOutDia / 2.0 - MaxinsulThk); } } }//foreach end //가대 오프셋,다리 길이 재설정 가이드 슈 일 떄 if (BoltType == 0) { //오프셋 Parameter paramRackOffset = Rack.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM); double rackOffset = paramRackOffset.AsDouble(); if (MinOffsetPipe != null) { paramRackOffset.Set(rackOffset - MinOffPipeOutDia / 2.0 - m_plateHgt - m_CoverThk * 2 - MininsulThk); //paramRackOffset.Set(rackOffset - MinOffsetPipe.Diameter / 2.0 - m_plateHgt - m_CoverThk * 2 - MininsulThk); } else { paramRackOffset.Set(rackOffset - MaxPipeOutDia / 2.0 - m_plateHgt - m_CoverThk * 2 - MaxinsulThk); //paramRackOffset.Set(rackOffset - MaxDiaPipe.Diameter / 2.0 - m_plateHgt - m_CoverThk * 2 - MaxinsulThk); } //다리 길이 double SupLength = 0; df = GetDefinition(Rack, "Support_Length"); if (df != null) { Parameter paramRackSupLen = Rack.get_Parameter(df); SupLength = paramRackSupLen.AsDouble(); if (MinOffsetPipe != null) { paramRackSupLen.Set(SelectLevel.Elevation - MinOffsetPipe.ReferenceLevel.Elevation - MinOffsetPipe.LevelOffset + m_plateHgt + m_CoverThk * 2 + MinOffPipeOutDia / 2.0 + MininsulThk + Unit.MMToFeet(150)); //paramRackSupLen.Set(SelectLevel.Elevation - MinOffsetPipe.ReferenceLevel.Elevation // - MinOffsetPipe.LevelOffset + m_plateHgt + m_CoverThk * 2 // + MinOffsetPipe.Diameter / 2.0 + MininsulThk + Unit.MMToFeet(150)); } else { paramRackSupLen.Set(SelectLevel.Elevation - MaxDiaPipe.ReferenceLevel.Elevation - MaxDiaPipe.LevelOffset + m_plateHgt + m_CoverThk * 2 + MaxPipeOutDia / 2.0 + MaxinsulThk + Unit.MMToFeet(150)); //paramRackSupLen.Set(SelectLevel.Elevation - MaxDiaPipe.ReferenceLevel.Elevation // - MaxDiaPipe.LevelOffset + m_plateHgt + m_CoverThk * 2 // + MaxDiaPipe.Diameter / 2.0 + MaxinsulThk + Unit.MMToFeet(150)); } } //if (MinOffsetPipe != null) // paramRackSupLen.Set(SupLength + MinOffsetPipe.Diameter / 2.0 + m_plateHgt + m_CoverThk * 2); //else // paramRackSupLen.Set(SupLength + MaxDiaPipe.Diameter / 2.0 + m_plateHgt + m_CoverThk * 2); } } /// /// 관경이 가장 큰 파이프 구하기 /// /// 파이프 리스트 /// 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; } 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; } } } }