using Autodesk.Revit.DB; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.UI; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System; using KDCS.Utils; namespace KMBIM { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] class CM_TORCOIL2 { double cdst = 0, wdst = 0, wdst2 = 0, tdst = 0, xdst = 0; bool FLG12 = false, FLG23 = false, FLG34 = false, FLG41 = false; double welNum = 0; double pch12, pch23, pch34, pch41; //외기부분 코일간격 조정을 대비해서 각 면 방향의 피치값을 설정함. double dst12, dst23, dst34, dst41, dst_to; XYZ trm1, trm2, trm3, trm4, vec12, vec23, vec34, vec41, vec21, vec32, vec43, vec14; List PntLst, PntLst2; bool exFlg = true, ExFlg1 = true, ExFlg2 = true; double OrgRem23, OrgRem12; Document doc; public bool DrawTorCoil2(UIApplication uiapp, double coildst, double walldst, double walldst2, double totaldst, double outdst, double offset, double coilDia, PipeType CoilType, PipingSystemType CoilSysType) { UIDocument uidoc = uiapp.ActiveUIDocument; Autodesk.Revit.ApplicationServices.Application app = uiapp.Application; doc = uidoc.Document; Autodesk.Revit.Creation.Application creApp = uiapp.Application.Create; Autodesk.Revit.Creation.Document creDoc = doc.Create; Autodesk.Revit.DB.View view = doc.ActiveView; //cdst = Unit.CovertToAPI(coildst, DisplayUnitType.DUT_MILLIMETERS); //wdst = Unit.CovertToAPI(walldst, DisplayUnitType.DUT_MILLIMETERS); //wdst2 = Unit.CovertToAPI(walldst2, DisplayUnitType.DUT_MILLIMETERS); //tdst = Unit.CovertToAPI(totaldst, DisplayUnitType.DUT_MILLIMETERS); //xdst = Unit.CovertToAPI(outdst, DisplayUnitType.DUT_MILLIMETERS); //coilDia = Unit.CovertToAPI(coilDia, DisplayUnitType.DUT_MILLIMETERS); cdst = Unit.MMToFeet(coildst); wdst = Unit.MMToFeet(walldst); wdst2 = Unit.MMToFeet(walldst2); tdst = Unit.MMToFeet(totaldst); xdst = Unit.MMToFeet(outdst); coilDia = Unit.MMToFeet(coilDia); offset = Unit.MMToFeet(offset); XYZ rm1 = new XYZ(); XYZ rm2 = new XYZ(); XYZ rm3 = new XYZ(); XYZ rm4 = new XYZ(); int yn = 0; Element elem; List lstElem = new List(); if (Util.PickPoint(uidoc, KMBIM.Revit.Tools.Properties.Resources.HCoil_Select_1st/*"시작점 지정 : "*/, ref rm1) == false) return false; if (Util.PickPoint(uidoc, KMBIM.Revit.Tools.Properties.Resources.HCoil_Select_2nd/*"두번째 점 지정 : "*/, ref rm2) == false) return false; if (FeetToMM(rm1, rm2) < cdst * 4) { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); return false; } else { using (Transaction transaction = new Transaction(doc)) { transaction.Start("Start"); elem = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), rm1, rm2); lstElem.Add(elem); transaction.Commit(); } } if (Util.PickPoint(uidoc, KMBIM.Revit.Tools.Properties.Resources.HCoil_Select_3rd/*"세번째 점 지정 : "*/, ref rm3) == false) { Util.DeleteElement(doc, lstElem); // 임시 박스 삭제 return false; } if (FeetToMM(rm2, rm3) < cdst * 4) { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); Util.DeleteElement(doc, lstElem); // 임시 박스 삭제 return false; } else { using (Transaction transaction = new Transaction(doc)) { transaction.Start("Start"); elem = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), rm2, rm3); lstElem.Add(elem); transaction.Commit(); } } if (Util.PickPoint(uidoc, KMBIM.Revit.Tools.Properties.Resources.HCoil_Select_4th/*"네번째 점 지정 : "*/, ref rm4) == false) { Util.DeleteElement(doc, lstElem); // 임시 박스 삭제 return false; } if (FeetToMM(rm3, rm4) < cdst * 4) { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); Util.DeleteElement(doc, lstElem); // 임시 박스 삭제 return false; } else { using (Transaction transaction = new Transaction(doc)) { transaction.Start("Start"); elem = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), rm3, rm4); lstElem.Add(elem); elem = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), rm4, rm1); lstElem.Add(elem); transaction.Commit(); } } pch12 = cdst; pch23 = cdst; pch34 = cdst; pch41 = cdst;//외기부분 코일간격 조정을 대비해서 각 면 방향의 피치값을 설정함 trm1 = rm1; trm2 = rm2; trm3 = rm3; trm4 = rm4;//존이 2개 이상일 경우에만 포인트 대체 //rm1 = trm1;rm2 = trm2;rm3 = trm3;rm4 = trm4; dst12 = rm1.DistanceTo(rm2); vec12 = (rm2 - rm1).Normalize(); dst23 = rm2.DistanceTo(rm3); vec23 = (rm3 - rm2).Normalize(); dst34 = rm3.DistanceTo(rm4); vec34 = (rm4 - rm3).Normalize(); dst41 = rm4.DistanceTo(rm1); vec41 = (rm1 - rm4).Normalize(); vec21 = (rm1 - rm2).Normalize(); vec43 = (rm3 - rm4).Normalize(); vec32 = (rm2 - rm3).Normalize(); vec14 = (rm4 - rm1).Normalize(); PntLst = PLINE_DRW_TORCOIL1(rm1, rm2, rm3, rm4, 0, uiapp, doc); dst_to = VRT_PL_DRW1(uiapp, doc, PntLst); dst_to = Unit.FeetToMM(dst_to) / 1000.0; //dst_to = Unit.CovertFromAPI(DisplayUnitType.DUT_METERS, dst_to); PntLst.Clear();//array 제거 FLG12 = false; FLG23 = false; FLG34 = false; FLG41 = false; FormCoilZone zoneDlg = new FormCoilZone(); zoneDlg.CoilLength = dst_to; zoneDlg.ZoneCount = 1; if (zoneDlg.ShowDialog() != DialogResult.OK) { Util.DeleteElement(doc, lstElem);//임시 박스 제거 return false; } else yn = zoneDlg.ZoneCount; int orgYn = yn; if (yn == 1) { while (ExFlg1) { Reference r = null; try { r = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "외기부분 코일간격을 조정할 면을 선택 또는 명령취소(ESC) : "); } catch { } if (r == null) { exFlg = false; break; } else { Element LineElement = doc.GetElement(r.ElementId); if (LineElement.Id == lstElem[0].Id) { pch12 = cdst * 0.5; FLG12 = true; ExFlg1 = false; } else if (LineElement.Id == lstElem[1].Id) { pch23 = cdst * 0.5; FLG23 = true; ExFlg1 = false; } else if (LineElement.Id == lstElem[2].Id) { pch34 = cdst * 0.5; FLG34 = true; ExFlg1 = false; } else if (LineElement.Id == lstElem[3].Id) { pch41 = cdst * 0.5; FLG41 = true; ExFlg1 = false; } else { TaskDialog.Show("오류", "잘못 선택된 면입니다. 다시 선택하세요."); } } while (ExFlg2) { Reference r2 = null; try { r2 = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "외기부분 코일간격을 조정할 면을 선택 또는 명령취소(esc) : "); } catch { } if (r2 == null) { Util.DeleteElement(doc, lstElem); // 임시 박스 삭제 goto End; } else { Element LineElement = doc.GetElement(r2.ElementId); if (LineElement.Id == lstElem[0].Id) { pch12 = cdst * 0.5; FLG12 = true; ExFlg2 = false; } else if (LineElement.Id == lstElem[1].Id) { pch23 = cdst * 0.5; FLG23 = true; ExFlg2 = false; } else if (LineElement.Id == lstElem[2].Id) { pch34 = cdst * 0.5; FLG34 = true; ExFlg2 = false; } else if (LineElement.Id == lstElem[3].Id) { pch41 = cdst * 0.5; FLG41 = true; ExFlg2 = false; } else { TaskDialog.Show("오류", "잘못 선택된 면입니다. 다시 선택하세요."); } } }//while end }//while end Util.DeleteElement(doc, lstElem);//임시 박스 제거 if (exFlg == true) { FormCoilOutAir OutAirDlg = new FormCoilOutAir(); OutAirDlg.OutAirCoilCnt = 2; OutAirDlg.ShowDialog(); if (OutAirDlg.OutAirCoilCnt / 2 == 0) exFlg = false; welNum = OutAirDlg.OutAirCoilCnt; } if (welNum != 0) welNum = Math.Floor(welNum / 2); List pipeElem = new List(); using (Transaction transaction = new Transaction(doc)) { transaction.Start("Start"); PntLst = PLINE_DRW_TORCOIL1(rm1, rm2, rm3, rm4, 0, uiapp, doc); dst_to = VRT_PL_DRW1(uiapp, doc, PntLst); List newPntLst = PtsElevation(PntLst, offset); if (newPntLst == null) return false; pipeElem = PIPE_ELEM_LIST(uiapp, doc, newPntLst); CreatePipe1(uidoc, doc, pipeElem, coilDia, CoilType, CoilSysType); PntLst.Clear(); //TaskDialog.Show("결과", "코일 길이 : " + Math.Floor(dst_to) + "m "); TaskDialog.Show("결과", "코일 길이 : " + Math.Round(Unit.FeetToMM(dst_to / 1000.0), 2) + "m "); transaction.Commit(); } }//존1개일때 else { List pipeElem = new List(); Util.DeleteElement(doc, lstElem);//임시 박스 제거 rm1 = trm2; rm2 = trm3; rm3 = trm4; rm4 = trm1; XYZ rm1_2, rm2_2, rm3_2, rm4_2, vecRM, plrpt; double InNum, tpNum, tot_dst, ydst1; //rm1~4재정의 됐으므로 dst,vec재정의 dst12 = rm1.DistanceTo(rm2); vec12 = (rm2 - rm1).Normalize(); dst23 = rm2.DistanceTo(rm3); vec23 = (rm3 - rm2).Normalize(); dst34 = rm3.DistanceTo(rm4); vec34 = (rm4 - rm3).Normalize(); dst41 = rm4.DistanceTo(rm1); vec41 = (rm1 - rm4).Normalize(); vec21 = (rm1 - rm2).Normalize(); vec43 = (rm3 - rm4).Normalize(); vec32 = (rm2 - rm3).Normalize(); vec14 = (rm4 - rm1).Normalize(); ydst1 = Math.Floor((rm1.DistanceTo(rm2) - ((cdst * orgYn) * 2)) / yn / cdst);//회오리2 에서는 존 수만큼 거리에서 뺀다. if (FLG41) pch41 = cdst; //존이 여러개인 경우 41라인의 피치는 cdst로 맞춰야 함. rm1_2 = rm2 + vec21 * (cdst * ydst1); rm4_2 = rm1_2 + vec23 * dst23; if (rm1_2.DistanceTo(rm2) > rm2.DistanceTo(rm3)) { OrgRem12 = cdst / 2; OrgRem23 = (trm1.DistanceTo(trm2) % cdst) / 2; } else { OrgRem12 = (trm2.DistanceTo(trm3) % cdst) / 2; OrgRem23 = cdst / 2; } InNum = Math.Floor(dst12 - ((OrgRem12 * 2)) / cdst); if (wdst > OrgRem12 * 0.5)//벽과 코일의 간격이 최소거리 미만인 경우 코일간격을 더한다.//wdst2 -> wdst 변경//2020-10-29 { InNum--; OrgRem12 = ((OrgRem12 * 2) + cdst) / 2; } rm2_2 = rm2 + vec21 * OrgRem12;//23라인을 나머지만큼 옮긴다. rm3_2 = rm3 + vec34 * OrgRem12; tpNum = Math.Floor(rm1_2.DistanceTo(rm2) / cdst); vecRM = (rm1_2 - rm2_2).Normalize(); if (orgYn == 2) { if (tpNum % 2 == 0)//마무리를 위해 라인수를 홀수로 정렬 rm1_2 = rm2_2 + vecRM * (cdst * (tpNum - 1)); else rm1_2 = rm2_2 + vecRM * (cdst * tpNum); } else { if (tpNum % 2 == 0)//마무리를 위해 라인수를 홀수로 정렬 rm1_2 = rm2_2 + vecRM * (cdst * (tpNum - 3)); else rm1_2 = rm2_2 + vecRM * (cdst * (tpNum - 2)); } plrpt = rm1_2 + vec23 * cdst; rm4_2 = GetIntersectionPoint(trm4, trm1, rm1_2, plrpt); tot_dst = OrgRem12 + (cdst * tpNum); PntLst2 = WYN_PLINE_DRW2(rm1_2, rm2_2, rm3_2, rm4_2, yn, uiapp, doc); if (PntLst2 == null || PntLst2.Count() == 0) goto End; else { using (Transaction trans = new Transaction(doc)) { trans.Start("CreatePipe"); List newPntLst = PtsElevation(PntLst2, offset); if (newPntLst == null) return false; pipeElem = END_PLINE_DRW2(newPntLst, yn, orgYn, rm2, rm1_2, trm1, trm2, trm3, trm4, uiapp, doc, offset); CreatePipe1(uidoc, doc, pipeElem, coilDia, CoilType, CoilSysType); trans.Commit(); } } if (FLG23) pch23 = cdst; //존이 여러개인 경우 두번째 존부터 23라인의 피치는 cdst로 맞춰야 함. yn--;//첫번째 코일은 작도했으므로 -1 while (yn > 0) { if (FLG41 && yn == 1) pch41 = cdst * 0.5;//존이 여러개인 경우 41라인의 피치는 설정값으로 재보정해야 함. rm3 = rm4_2 + vec34 * cdst;//일단 코일간격으로 두번째 존의 좌표를 재설정한다. rm2 = rm1_2 + vec34 * cdst; rm2 = rm2 + vec23 * (cdst * 2);//두번째 존에서는 벽과 코일간의 거리를 보정해야 한다. if (yn == 1) { vecRM = (trm3 - trm2).Normalize(); plrpt = rm2 + vecRM * cdst; rm1_2 = GetIntersectionPoint(trm1, trm2, rm2, plrpt); vecRM = (trm1 - trm4).Normalize(); plrpt = rm3 + vecRM * cdst; rm4_2 = GetIntersectionPoint(trm1, trm2, rm3, plrpt); vecRM = (trm3 - trm2).Normalize(); rm1_2 = rm1_2 + vecRM * ((cdst * orgYn * 2) + OrgRem12); rm4_2 = rm4_2 + vecRM * ((cdst * orgYn * 2) + OrgRem12); } else { if (tpNum % 2 == 1) tpNum--;//아래에서 다시 1을 - 시키므로 홀수인지 체크해서 처리함. if (orgYn > 3 && yn == 2) { vecRM = (trm2 - trm3).Normalize(); rm1_2 = rm2 + vecRM * (cdst * (tpNum + 1)); } else { vecRM = (trm2 - trm3).Normalize(); rm1_2 = rm2 + vecRM * (cdst * (tpNum - 1)); } vecRM = (rm3 - rm2).Normalize(); plrpt = rm1_2 + vecRM * cdst; rm4_2 = GetIntersectionPoint(trm4, trm1, rm1_2, plrpt); } tot_dst = tot_dst + (cdst * (tpNum + 1)); PntLst2.Clear(); PntLst2 = WYN_PLINE_DRW2(rm1_2, rm2, rm3, rm4_2, yn, uiapp, doc); if (PntLst == null || PntLst2.Count == 0) break; using (Transaction trans = new Transaction(doc)) { trans.Start("CreatePipe"); List newPntLst = PtsElevation(PntLst2, offset); if (newPntLst == null) return false; pipeElem.Clear(); pipeElem = END_PLINE_DRW2(newPntLst, yn, orgYn, rm2, rm1_2, trm1, trm2, trm3, trm4, uiapp, doc, offset); CreatePipe1(uidoc, doc, pipeElem, coilDia, CoilType, CoilSysType); trans.Commit(); } yn--; }//while end }//존 2개 이상일 때 End: return true; } public List PLINE_DRW_TORCOIL1(XYZ rm11, XYZ rm22, XYZ rm33, XYZ rm44, int wyn, UIApplication uiapp, Document doc) { if (FeetToMM(rm11, rm22) < cdst * 4 && FeetToMM(rm22, rm33) < cdst * 4) { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); return null; } double dst12 = 0, dst23 = 0, dst34 = 0, dst41 = 0; double comDist = 0, comDst1, comDst2, flgDst, tmPdst = 0, InNum, rem11; double wpch12, wpch21, wpch23, wpch32, wpch34, wpch43, wpch41, wpch14; List app1 = new List(), app2 = new List(); XYZ vec12, vec23, vec34, vec41, vec21, vec32, vec43, vec14; dst12 = rm11.DistanceTo(rm22); vec12 = (rm22 - rm11).Normalize(); dst23 = rm22.DistanceTo(rm33); vec23 = (rm33 - rm22).Normalize(); dst34 = rm33.DistanceTo(rm44); vec34 = (rm44 - rm33).Normalize(); dst41 = rm44.DistanceTo(rm11); vec41 = (rm11 - rm44).Normalize(); vec21 = (rm11 - rm22).Normalize(); vec32 = (rm22 - rm33).Normalize(); vec43 = (rm33 - rm44).Normalize(); vec14 = (rm44 - rm11).Normalize(); if (dst12 > dst23) comDist = dst23; else comDist = dst12; if ((FLG12 == true && FLG34 == true) && (FLG23 == true && FLG41 == true)) { tmPdst = comDist - ((cdst * 0.5 * ((welNum * 2) - 1)) * 2); InNum = System.Math.Floor(tmPdst / cdst); rem11 = tmPdst - (InNum * cdst); if (wdst > rem11 * 0.5)//wdst2 -> wdst 변경//2020-10-29 { InNum = InNum - 1; rem11 = tmPdst - (InNum * cdst); } InNum = InNum + (welNum * 4); } else if (FLG12 == true || FLG23 == true || FLG34 == true || FLG41 == true) { tmPdst = comDist - ((cdst * 0.5) * ((welNum * 2) - 1)); InNum = System.Math.Floor(tmPdst / cdst); rem11 = tmPdst - (InNum * cdst); if (wdst > (rem11 * 0.5))//wdst2 -> wdst 변경//2020-10-29 { InNum = InNum - 1; rem11 = tmPdst - (InNum * cdst); } InNum = InNum + (welNum * 2); } else { InNum = System.Math.Floor(comDist / cdst); rem11 = comDist - (InNum * cdst); if (wdst > (rem11 * 0.5))//wdst2 -> wdst 변경//2020-10-29 { InNum = InNum - 1; rem11 = comDist - (InNum * cdst); } } if (dst12 > dst23) { wpch12 = wdst; wpch21 = wdst; wpch23 = rem11 * 0.5; wpch32 = rem11 * 0.5; wpch34 = wdst; wpch43 = wdst; wpch41 = rem11 * 0.5; wpch14 = rem11 * 0.5; } else { wpch12 = rem11 * 0.5; wpch21 = rem11 * 0.5; wpch23 = wdst; wpch32 = wdst; wpch34 = rem11 * 0.5; wpch43 = rem11 * 0.5; wpch41 = wdst; wpch14 = wdst; } //TaskDialog.Show("길이", "나머지 : " + Unit.CovertToAPI(rem11,DisplayUnitType.DUT_MILLIAMPERES) + "\n코일라인 수 : " + InNum); XYZ srt1 = null, srt11 = null, srt2 = null, srt22 = null, srt3 = null, srt33 = null, srt4 = null , srt44 = null, tmPt = null, rt1 = null, rt2 = null, rt3 = null, rt4 = null , rt11 = null, rt22 = null, rt33 = null, rt44 = null; srt1 = rm11 + vec14 * wpch14; rt1 = rm11 + vec14 * (pch12 + wpch14); //Pyosi(uiapp, doc, srt1); //Pyosi(uiapp, doc, rt1); app1.Add(srt1);//바깥쪽 코일 시작점 app2.Add(rt1);//안쪽 코일 시작점 bool wFlg = true; int rep = 0; while (wFlg) { if (rep % 4 == 0) { if (rep < 4) { srt11 = CRS_DST_PNT(rm22, rm33, srt1, vec21, wpch21, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst12 - wpch21)) > Unit.FeetToMM(pch23 + pch41)) wFlg = true; else wFlg = false; srt1 = srt11; } else { tmPt = GetIntersectionPoint(srt1, srt2, srt4, Util.Polar(srt4, rm11, rm22, dst12)); if (Math.Floor((double)rep / 4) == welNum) srt11 = Util.Polar(tmPt, vec21, cdst + pch23); else if (Math.Floor((double)rep / 4) > welNum) srt11 = Util.Polar(tmPt, vec21, cdst * 2); else srt11 = Util.Polar(tmPt, vec21, pch23 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(srt11)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(srt4)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(flgDst - Unit.FeetToMM(cdst * 2)) < 0.01) wFlg = false; srt1 = srt11; } app1.Add(srt1); } else if (rep % 4 == 1) { if (rep < 4) { srt22 = CRS_DST_PNT(rm33, rm44, srt1, vec32, wpch32, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst23 - (wpch23 + wpch32))) > Unit.FeetToMM(pch34 + pch12)) wFlg = true; else wFlg = false; srt2 = srt22; } else { tmPt = GetIntersectionPoint(srt2, srt3, srt1, Util.Polar(srt1, rm22, rm33, dst23)); if (Math.Floor((double)rep / 4) == welNum) srt22 = Util.Polar(tmPt, vec32, cdst + pch34); else if (Math.Floor((double)rep / 4) > welNum) srt22 = Util.Polar(tmPt, vec32, cdst * 2); else srt22 = Util.Polar(tmPt, vec32, pch34 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(srt22)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(srt1)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(flgDst - Unit.FeetToMM(cdst * 2)) < 0.01) wFlg = false; srt2 = srt22; } app1.Add(srt2); } else if (rep % 4 == 2) { if (rep < 4) { srt33 = CRS_DST_PNT(rm44, rm11, srt2, vec43, wpch43, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst34 - (wpch34 + wpch43))) > Unit.FeetToMM(pch23 + pch41)) wFlg = true; else wFlg = false; srt3 = srt33; } else { tmPt = GetIntersectionPoint(srt3, srt4, srt2, Util.Polar(srt2, rm33, rm44, dst34)); if (Math.Floor((double)rep / 4) == welNum) srt33 = Util.Polar(tmPt, vec43, cdst + pch41); else if (Math.Floor((double)rep / 4) > welNum) srt33 = Util.Polar(tmPt, vec43, cdst * 2); else srt33 = Util.Polar(tmPt, vec43, pch41 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(srt33)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(srt2)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(flgDst - Unit.FeetToMM(cdst * 2)) < 0.01) wFlg = false; srt3 = srt33; } app1.Add(srt3); } else if (rep % 4 == 3) { if (rep < 4) { srt44 = CRS_DST_PNT(rm11, rm22, srt3, vec14, wpch14 + (pch12 * 2.0), uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst41 - (wpch41 + wpch14 + (pch12 * 2)))) > Unit.FeetToMM(pch34 + pch12)) wFlg = true; else wFlg = false; srt4 = srt44; } else { tmPt = GetIntersectionPoint(srt4, srt1, srt3, Util.Polar(srt3, rm44, rm11, dst41)); if (Math.Floor((double)rep / 4) == welNum) srt44 = Util.Polar(tmPt, vec14, cdst + pch12); else if (Math.Floor((double)rep / 4) > welNum) srt44 = Util.Polar(tmPt, vec14, cdst * 2); else srt44 = Util.Polar(tmPt, vec14, pch12 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(srt44)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(srt3)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(flgDst - Unit.FeetToMM(cdst * 2)) < 0.01) wFlg = false; srt4 = srt44; } app1.Add(srt4); } rep++; }//while end ////////////////////////////////////////리턴배관 wFlg = true; rep = 0; while (wFlg) { if (rep % 4 == 0) { if (rep < 4) { rt1 = CRS_DST_PNT(rm22, rm33, rt1, vec21, wpch21 + pch23, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst12 - (wpch12 + pch23))) > Unit.FeetToMM(pch23 + pch41)) wFlg = true; else wFlg = false; } else { tmPt = GetIntersectionPoint(rt1, rt2, rt4, Util.Polar(rt4, rm11, rm22, dst12)); if (Math.Floor((double)rep / 4) == welNum) rt11 = Util.Polar(tmPt, vec21, cdst * 2); else if (Math.Floor((double)rep / 4) > welNum) rt11 = Util.Polar(tmPt, vec21, cdst * 2); else rt11 = Util.Polar(tmPt, vec21, pch23 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(rt11)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(rt4)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(flgDst - Unit.FeetToMM(cdst * 2)) < 0.01) wFlg = false; rt1 = rt11; } app2.Add(rt1); } else if (rep % 4 == 1) { if (rep < 4) { rt2 = CRS_DST_PNT(rm33, rm44, rt1, vec32, wpch32 + pch34, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst23 - (wpch23 + wpch32 + pch34 + pch12))) > Unit.FeetToMM(pch34 + pch12)) wFlg = true; else wFlg = false; } else { tmPt = GetIntersectionPoint(rt2, rt3, rt1, Util.Polar(rt1, rm22, rm33, dst23)); if (Math.Floor((double)rep / 4) == welNum) rt22 = Util.Polar(tmPt, vec32, cdst * 2); else if (Math.Floor((double)rep / 4) > welNum) rt22 = Util.Polar(tmPt, vec32, cdst * 2); else rt22 = Util.Polar(tmPt, vec32, pch34 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(rt22)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(rt1)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(flgDst - Unit.FeetToMM(cdst * 2)) < 0.01) wFlg = false; rt2 = rt22; } app2.Add(rt2); } else if (rep % 4 == 2) { if (rep < 4) { rt3 = CRS_DST_PNT(rm44, rm11, rt2, vec43, wpch43 + pch41, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst34 - (wpch34 + wpch43 + pch23 + pch41))) > Unit.FeetToMM(pch23 + pch41)) wFlg = true; else wFlg = false; } else { tmPt = GetIntersectionPoint(rt3, rt4, rt2, Util.Polar(rt2, rm33, rm44, dst34)); if (Math.Floor((double)rep / 4) == welNum) rt33 = Util.Polar(tmPt, vec43, cdst * 2); else if (Math.Floor((double)rep / 4) > welNum) rt33 = Util.Polar(tmPt, vec43, cdst * 2); else rt33 = Util.Polar(tmPt, vec43, pch41 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(rt33)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(rt2)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(flgDst - Unit.FeetToMM(cdst * 2)) < 0.01) wFlg = false; rt3 = rt33; } app2.Add(rt3); } else if (rep % 4 == 3) { if (rep < 4) { rt4 = CRS_DST_PNT(rm11, rm22, rt3, vec14, wpch14 + (pch12 * 3), uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst41 - (wpch41 + wpch14 + (pch12 * 3)))) > Unit.FeetToMM(pch34 + pch12)) wFlg = true; else wFlg = false; if (Unit.FeetToMM(rt3.DistanceTo(rt4)) < Unit.FeetToMM(cdst * 2) || Math.Abs(rt3.DistanceTo(rt4) - (cdst * 2)) < 0.0000328084) wFlg = false; } else { tmPt = GetIntersectionPoint(rt4, rt1, rt3, Util.Polar(rt3, rm44, rm11, dst41)); if (Math.Floor((double)rep / 4) == welNum) rt44 = Util.Polar(tmPt, vec14, cdst * 2); else if (Math.Floor((double)rep / 4) > welNum) rt44 = Util.Polar(tmPt, vec14, cdst * 2); else rt44 = Util.Polar(tmPt, vec14, pch12 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(rt44)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(rt3)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(flgDst - Unit.FeetToMM(cdst * 2)) < 0.01) wFlg = false; rt4 = rt44; } app2.Add(rt4); } rep++; }//while end XYZ lastPt1, lastPt2; lastPt1 = app1.Last(); lastPt2 = app2.Last(); if (Unit.FeetToMM(lastPt1.DistanceTo(lastPt2)) < Unit.FeetToMM(cdst * 2)) { app1.RemoveAt(app1.Count - 1); app2.RemoveAt(app2.Count - 1); } //내부 마지막점에서 선이 매끄럽게 연결되도록 교차점 찾아 추가 //2020-10-20 파이프 내부 선 대각선으로 그리는 현상 조정 XYZ app1Last_1 = app1.Last(), app1Last_2 = app1[app1.Count() - 2], app1Last_3 = app1[app1.Count() - 3]; XYZ app2Last_1 = app2.Last(), app2Last_2 = app2[app2.Count() - 2], app2Last_3 = app2[app2.Count() - 3]; double dst1 = app1Last_1.DistanceTo(app1Last_2), dst2 = app1Last_2.DistanceTo(app1Last_3); app1Last_1 = app1.Last(); app1Last_2 = app1[app1.Count() - 2]; app1Last_3 = app1[app1.Count() - 3]; app2Last_1 = app2.Last(); app2Last_2 = app2[app2.Count() - 2]; app2Last_3 = app2[app2.Count() - 3]; XYZ Newpt1 = Util.Polar(app1Last_2, app1Last_2, app1Last_1, (app1Last_1.DistanceTo(app1Last_2) + cdst) / 2); XYZ Newpt2 = Util.Polar(app2Last_2, app2Last_2, app2Last_1, (app2Last_1.DistanceTo(app2Last_2) + cdst) / 2); //Pyosi(uiapp, doc, Newpt1); //Pyosi(uiapp, doc, Newpt2); app1.RemoveAt(app1.Count() - 1); app1.Add(Newpt1); app2.RemoveAt(app2.Count() - 1); app2.Add(Newpt2); app2.Reverse(); app1.AddRange(app2); return app1; } public XYZ CRS_DST_PNT(XYZ tp1, XYZ tp2, XYZ t1, XYZ tVec, double tPach, UIApplication uiapp, Document doc) { XYZ tp3, rPt, ttt; tVec.Normalize(); tp3 = t1 + tVec * tPach; ttt = GetIntersectionPoint(tp1, tp2, tp3, t1); //Pyosi(uiapp, doc, ttt); rPt = ttt + tVec * tPach; return rPt; } public double VRT_PL_DRW1(UIApplication uiapp, Document doc, List VAPP) { Autodesk.Revit.DB.View view = doc.ActiveView; double total_dst = 0, m_dst = 0; for (int i = 0; i < VAPP.Count() - 1; i++) { //Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), VAPP[i], VAPP[i + 1]); m_dst = VAPP[i].DistanceTo(VAPP[i + 1]); total_dst = total_dst + m_dst; } return total_dst; } public List PIPE_ELEM_LIST(UIApplication uiapp, Document doc, List VAPP) { Autodesk.Revit.DB.View view = doc.ActiveView; double total_dst = 0, m_dst = 0; List ElemList = new List(); for (int i = 0; i < VAPP.Count() - 1; i++) { var newLine = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), VAPP[i], VAPP[i + 1]); m_dst = VAPP[i].DistanceTo(VAPP[i + 1]); total_dst = total_dst + m_dst; ElemList.Add(newLine); } return ElemList; } public List WYN_PLINE_DRW2(XYZ rm11, XYZ rm22, XYZ rm33, XYZ rm44, int wyn, UIApplication uiapp, Document doc) { if (rm11.DistanceTo(rm22) < cdst * 4 || rm22.DistanceTo(rm33) < cdst * 4) { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); return null; } double dst12, dst23, dst34, dst41, comDist, comDst1, comDst2, flgDst, wpch21, wpch23, wpch32, wpch34, wpch43, wpch41, wpch14; XYZ srt1 = null, srt11 = null, srt2 = null, srt22 = null, srt3 = null, srt33 = null , srt4 = null, srt44 = null, rrt1 = null, rrt11 = null, rrt2 = null, rrt22 = null , rrt3 = null, rrt33 = null, rrt4 = null, rrt44 = null, tmPt = null, lastPt1 = null, lastPt2 = null, vec12, vec21, vec23, vec32, vec34, vec43, vec41, vec14, plrpt; List app1 = new List(), app2 = new List(); dst12 = rm11.DistanceTo(rm22); vec12 = (rm22 - rm11).Normalize(); dst23 = rm22.DistanceTo(rm33); vec23 = (rm33 - rm22).Normalize(); dst34 = rm33.DistanceTo(rm44); vec34 = (rm44 - rm33).Normalize(); dst41 = rm44.DistanceTo(rm11); vec41 = (rm11 - rm44).Normalize(); vec21 = (rm11 - rm22).Normalize(); vec32 = (rm22 - rm33).Normalize(); vec43 = (rm33 - rm44).Normalize(); vec14 = (rm44 - rm11).Normalize(); if (dst12 > dst23) comDist = dst23; else comDist = dst12; wpch21 = 0.0; wpch23 = OrgRem23; wpch32 = OrgRem23; wpch34 = 0.0; wpch43 = 0.0; wpch41 = OrgRem23; wpch14 = OrgRem23;//두번째 존에서는 벽에서의 거리를 전부 0으로 초기화함 srt1 = rm11 + vec14 * wpch14;//서플라이 시작점 rrt1 = rm11 + vec14 * (pch12 + wpch14);//리턴 시작점 //Pyosi(uiapp, doc, srt1); Pyosi(uiapp, doc, rrt1); app1.Add(srt1); app2.Add(rrt1); bool wFlg = true; int rep = 0; /////////////////////////////////서플라이 배관 포인트 구하는 루틴 /////////////////////// while (wFlg) { if (rep % 4 == 0) { if (rep < 4) { srt11 = GetIntersectionPoint(rm22, rm33, srt1, Util.Polar(srt1, vec12, pch23)); if (Math.Floor(Unit.FeetToMM(dst12 - wpch21)) > Unit.FeetToMM(pch23 + pch41)) wFlg = true; else wFlg = false; srt1 = srt11; } else { plrpt = srt4 + vec12 * dst12; tmPt = GetIntersectionPoint(srt1, srt2, srt4, Util.Polar(srt4, vec12, dst12)); if (Math.Floor((double)rep / 4) == welNum) srt11 = Util.Polar(tmPt, vec21, cdst + pch23); else if (Math.Floor((double)rep / 4) > welNum) srt11 = Util.Polar(tmPt, vec21, cdst * 2); else srt11 = Util.Polar(tmPt, vec21, cdst * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(srt11)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(srt4)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(Unit.FeetToMM(flgDst - (cdst * 2))) < 0.01) wFlg = false; srt1 = srt11;//포인트 환원 } app1.Add(srt1); }//rep % 4 ==0 end if (rep % 4 == 1) { if (rep < 4) { srt22 = CRS_DST_PNT(rm33, rm44, srt1, vec32, wpch32, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst23 - (wpch23 + wpch32))) > Unit.FeetToMM(pch34 + pch12)) wFlg = true; else wFlg = false; srt2 = srt22; } else { tmPt = GetIntersectionPoint(srt2, srt3, srt1, Util.Polar(srt1, vec23, dst23)); if (Math.Floor((double)rep / 4) == welNum) srt22 = Util.Polar(tmPt, vec32, cdst + pch34); else if (Math.Floor((double)rep / 4) > welNum) srt22 = Util.Polar(tmPt, vec32, cdst * 2); else srt22 = Util.Polar(tmPt, vec32, pch34 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(srt22)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(srt1)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(Unit.FeetToMM(flgDst - (cdst * 2))) < 0.01) wFlg = false; srt2 = srt22;//포인트 환원 } app1.Add(srt2); }//rep % 4 ==1 end if (rep % 4 == 2) { if (rep < 4) { srt33 = GetIntersectionPoint(rm44, rm11, srt2, Util.Polar(srt2, vec34, pch41)); if (Math.Floor(Unit.FeetToMM(dst34 - (wpch34 + wpch43))) > Unit.FeetToMM(pch23 + pch41)) wFlg = true; else wFlg = false; srt3 = srt33; } else { tmPt = GetIntersectionPoint(srt3, srt4, srt2, Util.Polar(srt2, vec34, dst34)); if (Math.Floor((double)rep / 4) == welNum) srt33 = Util.Polar(tmPt, vec43, cdst + pch41); else if (Math.Floor((double)rep / 4) > welNum) srt33 = Util.Polar(tmPt, vec43, cdst * 2); else srt33 = Util.Polar(tmPt, vec43, pch41 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(srt33)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(srt2)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(Unit.FeetToMM(flgDst - (cdst * 2))) < 0.01) wFlg = false; srt3 = srt33;//포인트 환원 } app1.Add(srt3); }//rep % 4 ==2 end if (rep % 4 == 3) { if (rep < 4) { srt44 = CRS_DST_PNT(rm11, rm22, srt3, vec14, wpch14 + (pch12 * 2.0), uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst41 - (wpch41 + wpch14 + (pch12 * 2)))) > Unit.FeetToMM(pch34 + pch12)) wFlg = true; else wFlg = false; srt4 = srt44; } else { tmPt = GetIntersectionPoint(srt4, srt1, srt3, Util.Polar(srt3, vec41, dst41)); if (Math.Floor((double)rep / 4) == welNum) srt44 = Util.Polar(tmPt, vec14, cdst + pch12); else if (Math.Floor((double)rep / 4) > welNum) srt44 = Util.Polar(tmPt, vec14, cdst * 2); else srt44 = Util.Polar(tmPt, vec14, pch12 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(srt44)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(srt3)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(Unit.FeetToMM(flgDst - (cdst * 2))) < 0.01) wFlg = false; srt4 = srt44;//포인트 환원 } app1.Add(srt4); }//rep % 4 ==3 end rep++; }//while end wFlg = true; rep = 0; /////////////////////////////////리턴 배관 포인트 구하는 루틴/////////////////////////////// while (wFlg) { if (rep % 4 == 0) { if (rep < 4) { rrt1 = CRS_DST_PNT(rm22, rm33, rrt1, vec21, pch23, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst12 - (wpch21 + pch23))) > Unit.FeetToMM(pch23 + pch41)) wFlg = true; else wFlg = false; } else { tmPt = GetIntersectionPoint(rrt1, rrt2, rrt4, Util.Polar(rrt4, vec12, dst12)); if (Math.Floor((double)rep / 4) == welNum) rrt11 = Util.Polar(tmPt, vec21, cdst * 2); else if (Math.Floor((double)rep / 4) > welNum) rrt11 = Util.Polar(tmPt, vec21, cdst * 2); else rrt11 = Util.Polar(tmPt, vec21, pch23 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(rrt11)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(rrt4)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(Unit.FeetToMM(flgDst - (cdst * 2))) < 0.01) wFlg = false; rrt1 = rrt11; } app2.Add(rrt1); }//rep % 4 == 0 end if (rep % 4 == 1) { if (rep < 4) { rrt2 = CRS_DST_PNT(rm33, rm44, rrt1, vec32, wpch32 + pch34, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst23 - (wpch23 + wpch32 + pch34 + pch12))) > Unit.FeetToMM(pch34 + pch12)) wFlg = true; else wFlg = false; } else { tmPt = GetIntersectionPoint(rrt2, rrt3, rrt1, Util.Polar(rrt1, vec23, dst23)); if (Math.Floor((double)rep / 4) == welNum) rrt22 = Util.Polar(tmPt, vec32, cdst * 2); else if (Math.Floor((double)rep / 4) > welNum) rrt22 = Util.Polar(tmPt, vec32, cdst * 2); else rrt22 = Util.Polar(tmPt, vec32, pch34 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(rrt22)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(rrt1)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(Unit.FeetToMM(flgDst - (cdst * 2))) < 0.01) wFlg = false; rrt2 = rrt22; } app2.Add(rrt2); }//rep % 4 == 1 end if (rep % 4 == 2) { if (rep < 4) { rrt3 = CRS_DST_PNT(rm44, rm11, rrt2, vec43, pch41, uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst34 - (wpch34 + wpch43 + pch23 + pch41))) > Unit.FeetToMM(pch23 + pch41)) wFlg = true; else wFlg = false; } else { tmPt = GetIntersectionPoint(rrt3, rrt4, rrt2, Util.Polar(rrt2, vec34, dst34)); if (Math.Floor((double)rep / 4) == welNum) rrt33 = Util.Polar(tmPt, vec43, cdst * 2); else if (Math.Floor((double)rep / 4) > welNum) rrt33 = Util.Polar(tmPt, vec43, cdst * 2); else rrt33 = Util.Polar(tmPt, vec43, pch41 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(rrt33)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(rrt2)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(Unit.FeetToMM(flgDst - (cdst * 2))) < 0.01) wFlg = false; rrt3 = rrt33; } app2.Add(rrt3); }//rep % 4 == 2 end if (rep % 4 == 3) { if (rep < 4) { rrt4 = CRS_DST_PNT(rm11, rm22, rrt3, vec14, wpch14 + (pch12 * 3), uiapp, doc); if (Math.Floor(Unit.FeetToMM(dst41 - (wpch41 + wpch14 + (pch12 * 3) + pch34))) > Unit.FeetToMM(pch34 + pch12)) wFlg = true; else wFlg = false; } else { tmPt = GetIntersectionPoint(rrt4, rrt1, rrt3, Util.Polar(rrt3, vec41, dst41)); if (Math.Floor((double)rep / 4) == welNum) rrt44 = Util.Polar(tmPt, vec14, cdst * 2); else if (Math.Floor((double)rep / 4) > welNum) rrt44 = Util.Polar(tmPt, vec14, cdst * 2); else rrt44 = Util.Polar(tmPt, vec14, pch12 * 2); comDst1 = Unit.FeetToMM(tmPt.DistanceTo(rrt44)); comDst2 = Unit.FeetToMM(tmPt.DistanceTo(rrt3)); flgDst = Math.Floor(comDst2 - comDst1); if (flgDst < Unit.FeetToMM(cdst * 2) || Math.Abs(Unit.FeetToMM(flgDst - (cdst * 2))) < 0.01) wFlg = false; rrt4 = rrt44; } app2.Add(rrt4); }//rep % 4 == 3 end rep++; }//while end lastPt1 = app1.Last(); lastPt2 = app2.Last(); if (Unit.FeetToMM(cdst * 2) > Unit.FeetToMM(lastPt1.DistanceTo(lastPt2))) { app1.RemoveAt(app1.Count() - 1); app2.RemoveAt(app2.Count() - 1); } //내부 마지막점에서 선이 매끄럽게 연결되도록 교차점 찾아 추가 //2020-10-20 파이프 내부 선 대각선으로 그리는 현상 조정 if (app1.Last().IsAlmostEqualTo(app1[app1.Count() - 2], 0.0000328084)) app1.RemoveAt(app1.Count() - 1); if (app2.Last().IsAlmostEqualTo(app2[app2.Count() - 2], 0.0000328084)) app2.RemoveAt(app2.Count() - 1); XYZ app1Last_1 = app1.Last(), app1Last_2 = app1[app1.Count() - 2], app1Last_3 = app1[app1.Count() - 3]; XYZ app2Last_1 = app2.Last(), app2Last_2 = app2[app2.Count() - 2], app2Last_3 = app2[app2.Count() - 3]; double dst1 = app1Last_1.DistanceTo(app1Last_2), dst2 = app1Last_2.DistanceTo(app1Last_3); //Pyosi(uiapp, doc, app1Last_1); //Pyosi(uiapp, doc, app1Last_2); //Pyosi(uiapp, doc, app1Last_3); if (dst1 > dst2) { app1.RemoveAt(app1.Count() - 1); app2.RemoveAt(app2.Count() - 1); app1Last_1 = app1.Last(); app1Last_2 = app1[app1.Count() - 2]; app1Last_3 = app1[app1.Count() - 3]; app2Last_1 = app2.Last(); app2Last_2 = app2[app2.Count() - 2]; app2Last_3 = app2[app2.Count() - 3]; XYZ Newpt1 = Util.Polar(app1Last_2, app1Last_2, app1Last_1, (app1Last_1.DistanceTo(app1Last_2) + cdst) / 2); XYZ Newpt2 = Util.Polar(app2Last_2, app2Last_2, app2Last_1, (app2Last_1.DistanceTo(app2Last_2) + cdst) / 2); app1.RemoveAt(app1.Count() - 1); app1.Add(Newpt1); app2.RemoveAt(app2.Count() - 1); app2.Add(Newpt2); } else { app1Last_1 = app1.Last(); app1Last_2 = app1[app1.Count() - 2]; app1Last_3 = app1[app1.Count() - 3]; app2Last_1 = app2.Last(); app2Last_2 = app2[app2.Count() - 2]; app2Last_3 = app2[app2.Count() - 3]; XYZ Newpt1 = Util.Polar(app1Last_2, app1Last_2, app1Last_1, (app1Last_1.DistanceTo(app1Last_2) + cdst) / 2); XYZ Newpt2 = Util.Polar(app2Last_2, app2Last_2, app2Last_1, (app2Last_1.DistanceTo(app2Last_2) + cdst) / 2); app1.RemoveAt(app1.Count() - 1); app1.Add(Newpt1); app2.RemoveAt(app2.Count() - 1); app2.Add(Newpt2); } app2.Reverse(); app1.AddRange(app2); return app1; } public List END_PLINE_DRW2(List APP, int yynn, int OrgYn, XYZ rm2, XYZ prm1, XYZ trm1, XYZ trm2, XYZ trm3, XYZ trm4, UIApplication uiapp, Document doc, double offset) { Level level = doc.ActiveView.GenLevel; XYZ pet0, pet00, pet000, pet1, pet11, pet111, plrpt, vecTRM; List ElemList = new List(); //Pyosi(uiapp, doc, APP.First()); //Pyosi(uiapp, doc, APP.Last()); APP.RemoveAt(0); APP.RemoveAt(APP.Count() - 1); if (yynn > 1) { pet0 = APP.Last(); vecTRM = (trm3 - trm2).Normalize(); plrpt = pet0 + vecTRM * 1; pet00 = GetIntersectionPoint(trm1, trm2, pet0, plrpt); vecTRM = (trm3 - trm2).Normalize(); pet00 = pet00 + vecTRM * (((OrgYn - yynn) * 2 * cdst) + OrgRem12 + cdst); vecTRM = (trm1 - trm2).Normalize(); plrpt = pet00 + vecTRM * cdst; pet000 = GetIntersectionPoint(trm1, trm4, pet00, plrpt); pet1 = APP.First(); vecTRM = (trm3 - trm2).Normalize(); plrpt = pet1 + vecTRM * 1; pet11 = GetIntersectionPoint(trm1, trm2, pet1, plrpt); vecTRM = (trm3 - trm2).Normalize(); pet11 = pet11 + vecTRM * (((OrgYn - yynn) * 2 * cdst) + OrgRem12); vecTRM = (trm1 - trm2).Normalize(); plrpt = pet11 + vecTRM * cdst; pet111 = GetIntersectionPoint(trm1, trm4, pet11, plrpt); pet00 = new XYZ(pet00.X, pet00.Y, level.Elevation + offset); pet000 = new XYZ(pet000.X, pet000.Y, level.Elevation + offset); pet11 = new XYZ(pet11.X, pet11.Y, level.Elevation + offset); pet111 = new XYZ(pet111.X, pet111.Y, level.Elevation + offset); APP.Add(pet00); APP.Add(pet000); APP.Reverse(); APP.Add(pet11); APP.Add(pet111); APP.Reverse(); } else { if (OrgYn > yynn) { pet0 = APP.Last(); vecTRM = (trm2 - trm3).Normalize(); plrpt = pet0 + vecTRM * 1; pet00 = GetIntersectionPoint(trm1, trm2, pet0, plrpt); vecTRM = (trm3 - trm2).Normalize(); pet00 = pet00 + vecTRM * (((OrgYn - yynn) * 2 * cdst) + OrgRem12 + cdst); vecTRM = (trm1 - trm2).Normalize(); plrpt = pet00 + vecTRM * 1; pet000 = GetIntersectionPoint(trm1, trm4, pet00, plrpt); pet1 = APP.First(); vecTRM = (trm2 - trm3).Normalize(); plrpt = pet1 + vecTRM * 1; pet11 = GetIntersectionPoint(trm1, trm2, pet1, plrpt); vecTRM = (trm3 - trm2).Normalize(); pet11 = pet11 + vecTRM * (((OrgYn - yynn) * 2 * cdst) + OrgRem12); vecTRM = (trm1 - trm2).Normalize(); plrpt = pet11 + vecTRM * 1; pet111 = GetIntersectionPoint(trm1, trm4, pet11, plrpt); pet00 = new XYZ(pet00.X, pet00.Y, level.Elevation + offset); pet000 = new XYZ(pet000.X, pet000.Y, level.Elevation + offset); pet11 = new XYZ(pet11.X, pet11.Y, level.Elevation + offset); pet111 = new XYZ(pet111.X, pet111.Y, level.Elevation + offset); APP.Add(pet00); APP.Add(pet000); APP.Reverse(); APP.Add(pet11); APP.Add(pet111); APP.Reverse(); } } //using (Transaction transaction = new Transaction(doc)) //{ // transaction.Start("Start"); Autodesk.Revit.DB.View view = doc.ActiveView; for (int i = 0; i < APP.Count() - 1; i++) { var newLine = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), APP.ElementAt(i), APP.ElementAt(i + 1)); ElemList.Add(newLine); } // transaction.Commit(); //} return ElemList; } public double FeetToMM(XYZ spt, XYZ ept) { double res = 0; res = System.Math.Round(Unit.FeetToMM(spt.DistanceTo(ept)), 4); //res = System.Math.Round(Unit.CovertFromAPI(DisplayUnitType.DUT_MILLIMETERS, spt.DistanceTo(ept)), 4); return res; } public double MMToFeet(XYZ spt, XYZ ept) { double res = 0; res = System.Math.Round(Unit.MMToFeet(spt.DistanceTo(ept)), 4); //res = System.Math.Round(Unit.CovertToAPI(spt.DistanceTo(ept), DisplayUnitType.DUT_MILLIMETERS), 4); return res; } public double Angle2D(XYZ spt, XYZ ept) { double degree = 0; XYZ vec; vec = (ept - spt).Normalize(); degree = System.Math.Round(Util.RTD(vec.AngleTo(XYZ.BasisX)), 3); return degree; } public XYZ GetIntersectionPoint(XYZ p1, XYZ p2, XYZ p3, XYZ p4) { double d = (p1.X - p2.X) * (p3.Y - p4.Y) - (p1.Y - p2.Y) * (p3.X - p4.X); if (d == 0) return null; double pre = (p1.X * p2.Y - p1.Y * p2.X), post = (p3.X * p4.Y - p3.Y * p4.X); double x = (pre * (p3.X - p4.X) - (p1.X - p2.X) * post) / d; double y = (pre * (p3.Y - p4.Y) - (p1.Y - p2.Y) * post) / d; XYZ resPt = new XYZ(x, y, p1.Z); return resPt; } public void CreatePipe1(UIDocument uidoc, Document document, List elementlist, double Coil_Dia, PipeType pipeType, PipingSystemType pipeSysType) { // (1) pipe 생성하기 // 1-1) pipe 생성에 필요한 속성 임의로 가져오기 //PipeType pipeType = new FilteredElementCollector(document).OfClass(typeof(PipeType)).FirstElement() as PipeType; //PipeType pipeType = new FilteredElementCollector(document).OfClass(typeof(PipeType)).ElementAt(1) as PipeType; Level level = document.ActiveView.GenLevel; //FilteredElementCollector sysCollector = new FilteredElementCollector(document); //sysCollector.OfCategory(BuiltInCategory.OST_PipingSystem); //ElementId pipeSysTypeId = sysCollector.FirstElementId(); //bool flag = true; // 1-2) 변수선언 Pipe newpipe = null; XYZ start = null; XYZ end = null; // 1-3) geometryElements 생성하기 List geometryCurve = new List(); for (int i = 0; i < elementlist.Count(); i++) { if (elementlist[i] is ModelLine) { ModelLine model = elementlist[i] as ModelLine; Curve cur = model.GeometryCurve; geometryCurve.Add(cur); } //GeometryElement geometry = elementlist.ElementAt(i).get_Geometry(new Options()); //geometryElements.Add(geometry); } // 1-4) 트랜젝션 실행 try { // 1-5) 파이프 생성 후 리스트에 담기 List pipes = new List(); List elePipe = new List(); //foreach (GeometryElement geometryele in geometryElements) //{ // foreach (GeometryObject obj in geometryele) // { foreach (Curve cur in geometryCurve) { start = cur.GetEndPoint(0); end = cur.GetEndPoint(1); if (pipeType != null) { newpipe = Pipe.Create(document, pipeSysType.Id, pipeType.Id, level.Id, start, end); pipes.Add(newpipe); //MessageBox.Show("1"); Element element = document.GetElement(newpipe.Id as ElementId); elePipe.Add(element); // 1-6) fitting 할 elbow 굵기에 맞게 pipe 굵기 설정하기 ElementId elementId = newpipe.Id as ElementId; //Parameter parameter = element.LookupParameter("지름"); newpipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(Coil_Dia); //// 1-7) Pipe 의 연결할 elbow Type 지정하기 //// Revit api 로 pipe fitting 할 경우 연결할 elbowType의 기본값이 none이기 때문에 꼭! Routing Preferences에서 설정해주어야한다. //ElementType elbowType = new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_PipeFitting).OfClass(typeof(ElementType)).Cast().Where(x => x.FamilyName.Contains("M_엘보")).FirstOrDefault(); //RoutingPreferenceManager rpm = newpipe.PipeType.RoutingPreferenceManager; //rpm.AddRule(RoutingPreferenceRuleGroupType.Elbows, new RoutingPreferenceRule(elbowType.Id, "Set Elbow fitting Type")); //int routingPerenceGroupCnt = rpm.GetNumberOfRules(RoutingPreferenceRuleGroupType.Elbows); //if (routingPerenceGroupCnt > 1) //{ // for (int k = 0; k < routingPerenceGroupCnt - 1; k++) // { // rpm.RemoveRule(RoutingPreferenceRuleGroupType.Elbows, 0); // } //} } } // } //} // (2) Pipe 연결시키기 // 2-1) transaction 안에서 종류 설정했으므로 중간에 새로고침하여 elbow 종류 설정한 값 적용되도록 하기 document.Regenerate(); // 2-2) 연결시킬 2개의 파이프 connector 가져오기위해, connectormanager로 connectors 뽑아내기 for (int i = 0; i < pipes.Count() - 1; i++) { ConnectorManager pipe_connectorManager1 = pipes.ElementAt(i).ConnectorManager; ConnectorSet pipe_connectorSet1 = pipe_connectorManager1.Connectors; ConnectorManager pipe_connectorManager2 = pipes.ElementAt(i + 1).ConnectorManager; ConnectorSet pipe_connectorSet2 = pipe_connectorManager2.Connectors; // 2-3) 파이프가 가지고 있는 connectors 에서 연결시킬 connector 뽑아내기 Connector pipe_connector1 = null; Connector pipe_connector2 = null; double minDist = double.MaxValue; foreach (Connector connector1 in pipe_connectorSet1) { foreach (Connector connector2 in pipe_connectorSet2) { double d = connector1.Origin.DistanceTo(connector2.Origin); if (d < minDist) { pipe_connector1 = connector1; pipe_connector2 = connector2; minDist = d; } } } // 2-4) 2개의 파이프 연결시키기 try { FamilyInstance fitting = document.Create.NewElbowFitting(pipe_connector1, pipe_connector2); } catch { } } // (3) pipe와 겹치는 line 삭제하기 foreach (Element element in elementlist) { if (element == null) continue; ElementId elementId = element.Id; document.Delete(elementId); } } catch (Exception) { MessageBox.Show("Pipe 간의 각도가 너무 크거나 작습니다. \n조정 후 다시 시도해주세요"); } } //포인트들 현재 레벨의 z값만큼 올리기. public List PtsElevation(List m_Ptlst, double offset) { List ptLst = new List(); Level level = doc.ActiveView.GenLevel; if (level == null) { TaskDialog.Show("뷰 오류", "현재 뷰에서 레벨을 참조할 수 없습니다."); return null; } foreach (XYZ pt in m_Ptlst) { XYZ ElevationPt = new XYZ(pt.X, pt.Y, level.Elevation + offset); ptLst.Add(ElevationPt); } return ptLst; } } }