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_OUTCOIL { double cdst = 0, wdst = 0, wdst2 = 0, tdst = 0, xdst = 0; int yn = 0, OrgYn; double welNum; double pch12, pch23, pch34, pch41; //외기부분 코일간격 조정을 대비해서 각 면 방향의 피치값을 설정함. double dst12, dst23, dst34, dst41, dst_to, rem12, rem34, rem1, InNum12, InNum34, InNum; XYZ trm1, trm2, trm3, trm4, vec12, vec23, vec34, vec41, vec21, vec32, vec43; List PntLst; bool exFlg = true, drawFlg; double ptch, OrgPtch; XYZ orgRm1, orgRm2, orgRm3, orgRm4, OrgPt0; List OrgPtList = new List(); Document doc; UIDocument uidoc; public bool DrawOutCoil(UIApplication uiapp, double coildst, double walldst, double walldst2, double totaldst, double outdst, double offset, double coilDia, PipeType CoilType, PipingSystemType CoilSysType) { 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.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(); XYZ rm1_2, rm4_2, pt_2, pt_3, tmpRm3; double dstChkFlg = 0; welNum = 0;//초기화 해야함 ptch = cdst; OrgPtch = ptch; 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(); } } trm1 = rm1; trm2 = rm2; trm3 = rm3; trm4 = rm4; pch12 = cdst; pch23 = cdst; pch34 = cdst; pch41 = cdst;//외기부분 코일간격 조정을 대비해서 각 면 방향의 피치값을 설정함 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(); //나머지 rem12 = dst12 % cdst; rem34 = dst34 % cdst; if (dst12 > dst34)//벽과 코일의 간격이 50mm 미만인 경우 코일간격을 더한다. rem1 = rem34; else rem1 = rem12; //라인수 InNum12 = Math.Floor((dst12 - rem1) / cdst); InNum34 = Math.Floor((dst34 - rem1) / cdst); if (dst12 > dst34)//비틀어진 사각형 대비해 짧은쪽 거리의 나머지를 설정 InNum = InNum34; else InNum = InNum12; if (InNum % 2 == 0)//라인수가 짝수인 경우만 1을 빼고 홀수이면 그대로 적용하면 실제 거리가 나온다. { InNum--; InNum12--; InNum34--; rem1 = rem1 + cdst; rem12 = rem12 + cdst; rem34 = rem34 + cdst; } if (wdst * 2 > rem1)//wdst2 -> wdst 변경//2020-10-29 { if (InNum % 2 == 0) { rem1 = rem1 + cdst; rem12 = rem12 + cdst; rem34 = rem34 + cdst; InNum--; InNum12--; InNum34--; } else { rem1 = rem1 + (cdst * 2); rem12 = rem12 + (cdst * 2); rem34 = rem34 + (cdst * 2); InNum = InNum - 2; InNum12 = InNum12 - 2; InNum34 = InNum34 - 2; } } else { if (InNum % 2 == 0) { rem1 = rem1 + cdst; rem12 = rem12 + cdst; rem34 = rem34 + cdst; InNum--; InNum12--; InNum34--; } } //TaskDialog.Show("결과", "라인수= " + (InNum + 1) + "\n나머지= " + Math.Round(rem1, 2)); double wpch12, wpch21, wpch23, wpch32, wpch34, wpch43, wpch41, wpch14; wpch12 = rem12 * 0.5; wpch21 = rem12 * 0.5; wpch23 = wdst; wpch32 = wdst; wpch34 = rem34 * 0.5; wpch43 = rem34 * 0.5; wpch41 = wdst; wpch14 = wdst; PntLst = EX1_BAND_DRW_PNT(rm1, rm2, rm3, rm4, 0, rem12, trm1, trm2, trm3, uiapp, doc); List resElem = new List(); dst_to = EX1_VRT_PL_DRW(PntLst, uiapp, doc, resElem); dst_to = Unit.FeetToMM(dst_to) / 1000.0; Util.DeleteElement(doc, resElem); 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; OrgYn = yn; if (yn == 0 || yn == 1) { if (Unit.FeetToMM(dst23) / 1000.0 > Unit.FeetToMM(xdst)) { TaskDialog.Show("결과", "외기라인의 길이 " +Math.Round(Unit.FeetToMM(dst23) / 1000.0, 1) + "m가 " + Unit.FeetToMM(xdst) + "m를 초과하였습니다!!"); Util.DeleteElement(doc, lstElem); // 작도 전 임시 박스 삭제 Exceed_Excoil1(rm1, rm2, rm3, rm4, uiapp, doc, coilDia, CoilType, CoilSysType, offset);//서브 메인 } else { FormCoilOutAir2 OutAirDlg = new FormCoilOutAir2(); OutAirDlg.OutAirCoilCnt = 0; if (OutAirDlg.ShowDialog() != DialogResult.OK) { Util.DeleteElement(doc, lstElem); // 임시 박스 삭제 goto End; } else welNum = OutAirDlg.OutAirCoilCnt; Util.DeleteElement(doc, lstElem); //작도 전 임시 박스 삭제 if (welNum >= 2) { if (welNum % 2 != 0)//외기코일수가 홀수인 경우 1을더해준다 welNum = welNum + 1; InNum12 = Math.Floor(((dst12 - ((cdst * 0.5) * (welNum - 1))) / cdst));//외기코일이 있는 경우 라인수 InNum34 = Math.Floor(((dst34 - ((cdst * 0.5) * (welNum - 1))) / cdst)); if (dst12 > dst34)//비틀어진 사각형 대비해서 짧은 쪽의 거리의 나머지 설정 InNum = InNum34; else InNum = InNum12; if (InNum % 2 != 0) { InNum--; InNum12--; InNum34--; } rem12 = (dst12 - ((((cdst * 0.5) * (welNum - 1))) + (InNum12 * cdst))); rem34 = (dst34 - ((((cdst * 0.5) * (welNum - 1))) + (InNum34 * cdst))); if (dst12 > dst34) rem1 = rem34; else rem1 = rem12; if (wdst * 2 > rem1)//wdst2 -> wdst 변경//2020-10-29 { InNum12 = Math.Floor(((dst12 - cdst) - ((cdst * 0.5) * (welNum - 1))) / cdst); InNum34 = Math.Floor(((dst34 - cdst) - ((cdst * 0.5) * (welNum - 1))) / cdst); if (dst12 > dst34)//비틀어진 사각형 대비해 짧은 쪽 거리의 나머지를 설정함. InNum = InNum34; else InNum = InNum12; if (InNum % 2 != 0) { InNum--; InNum12--; InNum34--; }//fmod!=0 rem12 = dst12 - (((cdst * 0.5) * (welNum - 1)) + (InNum12 * cdst)); rem34 = dst12 - (((cdst * 0.5) * (welNum - 1)) + (InNum34 * cdst)); if (dst12 > dst34) rem1 = rem34; else rem1 = rem12; }//wdst2*2>rem1 } else if (welNum == 0 || welNum == 1) { goto back; } else goto End; //존 0 또는 1일 경우 기본작도 back: rm1 = Util.Polar(rm1, rm1, rm2, rem1 * 0.5); rm4 = Util.Polar(rm4, rm4, rm3, rem1 * 0.5); PntLst = EX1_BAND_DRW_PNT(rm1, rm2, rm3, rm4, 0, rem12, trm1, trm2, trm3, uiapp, doc); PntLst.RemoveAt(0);//겹치는점 때문에 하나지움 //m_Draw.DrawPLine(PntLst, 0.0); //if (drawFlg == false) List pipeElem = new List(); using(Transaction trans=new Transaction(doc)) { trans.Start("CreatePipe"); List newPntLst = PtsElevation(PntLst, offset); if (newPntLst == null) return false; pipeElem = EX1_BAND_PL_DRW(newPntLst, yn, rm1, trm1, trm2, trm3, trm4, uiapp, doc , offset); PntLst.RemoveAt(PntLst.Count() - 1); CreatePipe1(uidoc, doc, pipeElem, coilDia, CoilType, CoilSysType); trans.Commit(); } } }//존 1개일 때 end else {//존 1개 이상 Util.DeleteElement(doc, lstElem); // 작도 전 임시 박스 삭제 //rm1 rm4 포인트 보정 rm1 = Util.Polar(rm1, rm1, rm2, rem1 * 0.5); rm4 = Util.Polar(rm4, rm4, rm3, rem1 * 0.5); double ydst1 = Math.Floor((rm1.DistanceTo(rm2) / yn) / ptch) + 1;//밴드형은 1을 더해야함 if (ydst1 % 2 == 1) ydst1--; if (OrgYn == 2) {//2존일 경우에는 오히려 두번째가 너무 길게나옴 rm1_2 = Util.Polar(rm2, rm2, rm1, ptch * ydst1); rm4_2 = Util.Polar(rm3, rm3, rm4, ptch * ydst1); } else { rm1_2 = Util.Polar(rm2, rm2, rm1, ptch * (ydst1 - 1)); rm4_2 = Util.Polar(rm3, rm3, rm4, ptch * (ydst1 - 1)); } PntLst = EX1_BAND_DRW_PNT(rm1_2, rm2, rm3, rm4_2, 0, rem12, trm1, trm2, trm3, uiapp, doc); PntLst.RemoveAt(0);//점이겹쳐있어 fillet시 원이생겨 마지막점 제거 List newPntLst = PtsElevation(PntLst, offset); if (newPntLst == null) return false; if (PntLst.Count() > 0) { List pipeElem = new List(); using(Transaction trans=new Transaction(doc)) { trans.Start("CreatePipe"); pipeElem = EX1_BAND_PL_DRW(newPntLst, yn, rm1_2, trm1, trm2, trm3, trm4, uiapp, doc, offset); CreatePipe1(uidoc, doc, pipeElem, coilDia, CoilType, CoilSysType); trans.Commit(); } newPntLst.RemoveAt(newPntLst.Count() - 1); //EX1_BAND_PL_DRW에서 나온 배열에 1개 더추가되어 끝점 삭제함 yn = yn - 1; newPntLst.Reverse(); pt_2 = newPntLst.ElementAt(0); pt_3 = newPntLst.ElementAt(1); newPntLst.Reverse(); dstChkFlg = 1; //Pyosi(uiapp, doc, pt_2); TaskDialog.Show("1", "pt_2"); //Pyosi(uiapp, doc, pt_3); TaskDialog.Show("1", "pt_3"); while (yn > 0) { rm2 = pt_2; tmpRm3 = rm3; rm3 = GetIntersectionPoint(pt_2, pt_3, rm3, rm4); if (rm3 == XYZ.Zero) {////// PntLst.Reverse(); pt_2 = PntLst.First(); pt_3 = PntLst.ElementAt(1); PntLst.Reverse(); rm2 = pt_2; rm3 = GetIntersectionPoint(pt_2, pt_3, tmpRm3, rm4); } if (yn == 1) { rm1_2 = GetIntersectionPoint(rm1, rm4, rm2, Util.Polar(rm2, trm1, trm2, ptch)); rm4_2 = rm4; } else { if (OrgYn == 2) { rm1_2 = Util.Polar(rm2, Util.RotateVector(vec12, Math.PI), ptch * ydst1); rm4_2 = Util.Polar(rm3, rm3, rm4, ptch * ydst1); } else { rm1_2 = Util.Polar(rm2, Util.RotateVector(vec12, Math.PI), ptch * (ydst1 + 1)); rm4_2 = Util.Polar(rm3, rm3, rm4, ptch * (ydst1 + 1)); }//orgyn==2 } //PntLst.RemoveRange(0, PntLst.Count() - 1); PntLst.Clear(); newPntLst.Clear(); PntLst = EX1_BAND_DRW_PNT(rm1_2, rm2, rm3, rm4_2, yn, rem12, trm1, trm2, trm3, uiapp, doc); PntLst.RemoveAt(0);//점이겹쳐있어 fillet시 원이생겨 마지막점 제거 newPntLst = PtsElevation(PntLst, offset); if (newPntLst == null) return false; if (PntLst.Count() > 0) { pipeElem.Clear(); using(Transaction trans=new Transaction(doc)) { trans.Start("CreatePipe"); pipeElem = EX1_BAND_PL_DRW(newPntLst, yn, rm1_2, trm1, trm2, trm3, trm4, uiapp, doc, offset); CreatePipe1(uidoc, doc, pipeElem, coilDia, CoilType, CoilSysType); trans.Commit(); } newPntLst.RemoveAt(newPntLst.Count() - 1);//EX1_BAND_PL_DRW에서 나온 배열에 1개 더추가되어 끝점 삭제함 newPntLst.Reverse(); pt_2 = newPntLst.First(); pt_3 = newPntLst.ElementAt(1); newPntLst.Reverse(); } yn = yn - 1; dstChkFlg = dstChkFlg + 1; }//while end } } End: return true; } public List EX1_BAND_PL_DRW(List APP, int yynn, XYZ PRM1, XYZ trm1, XYZ trm2, XYZ trm3, XYZ trm4, UIApplication uiapp, Document doc, double offset) { Level level = doc.ActiveView.GenLevel; XYZ pet0, pet1, pet00, pet11; //ads_name PLN1, joinEnt; double Perimeter, vpl_lth = 0; List ElemList = new List(); if (yynn != 1) { pet0 = APP.First(); pet1 = APP.Last(); pet00 = GetIntersectionPoint(trm1, trm4, pet0, Util.Polar(pet0, trm2, trm1, cdst)); pet11 = GetIntersectionPoint(trm1, trm4, pet1, Util.Polar(pet1, trm2, trm1, cdst)); pet00 = new XYZ(pet00.X, pet00.Y, level.Elevation + offset); pet11 = new XYZ(pet11.X, pet11.Y, level.Elevation + offset); APP.Add(pet11); APP.Reverse(); APP.Add(pet00); APP.Reverse(); Autodesk.Revit.DB.View view = doc.ActiveView; //using (Transaction transaction = new Transaction(doc)) //{ // // transaction.Start("Start"); for (int i = 0; i < APP.Count() - 1; i++) { var newLine = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), APP[i], APP[i + 1]); Perimeter = APP[i].DistanceTo(APP[i + 1]); vpl_lth = vpl_lth + Perimeter; ElemList.Add(newLine); } // transaction.Commit(); //} } else //yynn==1 { pet0 = APP.ElementAt(0);//if(OrgPt0)OrgPt0 (nth 0 APP) pet1 = APP.Last(); pet00 = GetIntersectionPoint(trm1, trm4, pet0, Util.Polar(pet0, trm2, trm1, cdst)); pet11 = GetIntersectionPoint(trm1, trm4, pet1, Util.Polar(pet1, trm2, trm1, cdst)); pet00 = new XYZ(pet00.X, pet00.Y, level.Elevation + offset); pet11 = new XYZ(pet11.X, pet11.Y, level.Elevation + offset); APP.Add(pet11); if (OrgPtList.Count() > 0) { OrgPtList.Reverse(); OrgPtList.Add(pet00); OrgPtList.Reverse(); } else { APP.Reverse(); APP.Add(pet00); APP.Reverse(); } Autodesk.Revit.DB.View view = doc.ActiveView; //using (Transaction transaction = new Transaction(doc)) //{ // transaction.Start("Start"); for (int i = 0; i < APP.Count() - 1; i++) { var newLine = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), APP[i], APP[i + 1]); Perimeter = APP[i].DistanceTo(APP[i + 1]); vpl_lth = vpl_lth + Perimeter; ElemList.Add(newLine); } // transaction.Commit(); //} if (OrgPtList.Count() > 0) { //using (Transaction transaction = new Transaction(doc)) //{ // transaction.Start("Start"); for (int i = 0; i < APP.Count() - 1; i++) { var newLine = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), APP[i], APP[i + 1]); Perimeter = APP[i].DistanceTo(APP[i + 1]); vpl_lth = vpl_lth + Perimeter; ElemList.Add(newLine); } // transaction.Commit(); //} Util.DeleteElement(doc, ElemList); } } //TaskDialog.Show("결과", "코일 길이 : " + Math.Round(vpl_lth, 1)); return ElemList; } public List Excd_BAND_DRW_PNT2(XYZ drm1, XYZ drm2, XYZ drm3, XYZ drm4, int wyn, double rem12, XYZ trm1, XYZ trm2, XYZ trm3, XYZ trm4, UIApplication uiapp, Document doc) { double dst00, dst01, dst02, dst03, dst12, dst23, dst34, dst_chk = 0; XYZ vec12, vec21, vec23, vec34, vec43, vec41, vec14; XYZ srt00, srt11, srt12, srt13, srt14, srt15, srt16, srt21, srt11_1, srt12_1; List app1 = new List(); if (drm1.DistanceTo(drm2) < (cdst * 2.5)) { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); } dst00 = drm1.DistanceTo(drm2); dst01 = dst00; dst02 = dst00; dst03 = dst00;//비교할 거리를 최기화함 vec12 = (drm2 - drm1).Normalize(); vec21 = (drm1 - drm2).Normalize(); vec23 = (drm3 - drm2).Normalize(); vec32 = (drm2 - drm3).Normalize(); vec34 = (drm4 - drm3).Normalize(); vec43 = (drm3 - drm4).Normalize(); vec41 = (drm1 - drm4).Normalize(); vec14 = (drm4 - drm1).Normalize(); dst12 = drm1.DistanceTo(drm2); dst23 = drm2.DistanceTo(drm3); dst34 = drm3.DistanceTo(drm4); srt11 = Util.Polar(drm1, drm1, drm4, OrgPtch); srt12 = CRS_DST_PNT(drm2, drm3, srt11, vec21, OrgPtch, uiapp, doc); srt13 = CRS_DST_PNT(drm3, drm4, srt12, vec32, OrgPtch, uiapp, doc); srt14 = EX1_NEA_POINT(srt11, srt12, srt13, OrgPtch, uiapp, doc); srt15 = CRS_DST_PNT(drm1, drm2, srt14, vec23, (OrgPtch * 2), uiapp, doc); srt16 = EX1_NEA_POINT(srt11, srt14, srt15, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt15, srt16); srt00 = srt16; srt11_1 = Util.Polar(srt11, vec12, OrgPtch); srt12_1 = GetIntersectionPoint(trm1, trm4, srt11_1, Util.Polar(srt11_1, drm1, drm4, cdst)); app1.Add(srt12_1); app1.Add(srt11_1); app1.Add(srt12); app1.Add(srt13); app1.Add(srt14); app1.Add(srt15); bool endFlg1 = true, endFlg2 = true; double rep = 4; while (endFlg2) { if (rep == 4) { app1.Add(srt16); } if (rep % 4 == 1) { srt00 = EX1_NEA_POINT(srt11, srt16, srt00, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt00, Util.Polar(srt00, drm3, drm4, OrgPtch)); dst01 = srt00.DistanceTo(srt21); if (endFlg1 == false) endFlg2 = false; }//fmod==1 else if (rep % 4 == 2) { srt16 = srt00; srt00 = CRS_DST_PNT(drm1, drm2, srt00, vec23, (OrgPtch * 2), uiapp, doc); dst02 = srt00.DistanceTo(srt21); }//fmod==2 else if (rep % 4 == 3) { if (welNum > 0) srt00 = EX1_NEA_POINT(srt11, srt16, srt00, ptch, uiapp, doc); else srt00 = EX1_NEA_POINT(srt11, srt16, srt00, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt00, Util.Polar(srt00, drm2, drm1, OrgPtch)); srt16 = app1.Last(); dst00 = srt00.DistanceTo(srt21); }//fmod==3 else if (rep % 4 == 0) { srt00 = CRS_DST_PNT(drm3, drm4, srt00, vec32, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt00, Util.Polar(srt00, drm3, drm4, OrgPtch)); srt16 = app1.Last(); dst00 = srt00.DistanceTo(srt21); }//fmod==0 app1.Add(srt00); if (rep % 4 == 0) dst_chk = dst00; else if (rep % 4 == 1) dst_chk = dst01; else if (rep % 4 == 2) dst_chk = dst02; else if (rep % 4 == 3) dst_chk = dst03; if (dst_chk == dst01 || dst_chk < (OrgPtch * 3)) { if (dst_chk < (OrgPtch * 3)) endFlg1 = false; } if (dst_chk == dst02 || dst_chk < (OrgPtch * 3)) { if (dst_chk < (OrgPtch * 3)) endFlg1 = false; } rep++; }//while end return app1; } public List Excd_BAND_DRW_PNT(XYZ drm1, XYZ drm2, XYZ drm3, XYZ drm4, int wyn, double rem12, XYZ trm1, XYZ trm2, XYZ trm3, XYZ trm4, UIApplication uiapp, Document doc) { double dst00, dst01, dst02, dst03, dst12, dst23, dst34, dst_chk; XYZ vec12 = null, vec23 = null, vec32 = null, vec34 = null, vec43 = null, vec41 = null, vec14 = null; XYZ srt00, srt11, srt12, srt13, srt14, srt15, srt16, srt21, srt11_1, srt12_1, srt13_1; List app1 = new List(); if (drm1.DistanceTo(drm2) < (cdst * 1.5)) { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); } dst00 = drm1.DistanceTo(drm2); dst01 = dst00; dst02 = dst00; dst03 = dst00;//비교할 거리를 최기화함 vec12 = (drm2 - drm1).Normalize(); vec21 = (drm1 - drm2).Normalize(); vec23 = (drm3 - drm2).Normalize(); vec32 = (drm2 - drm3).Normalize(); vec34 = (drm4 - drm3).Normalize(); vec43 = (drm3 - drm4).Normalize(); vec41 = (drm1 - drm4).Normalize(); vec14 = (drm4 - drm1).Normalize(); dst12 = drm1.DistanceTo(drm2); dst23 = drm2.DistanceTo(drm3); dst34 = drm3.DistanceTo(drm4); srt11 = Util.Polar(drm1, vec12, (rem12 * 0.5) + OrgPtch); srt12 = GetIntersectionPoint(drm2, drm3, srt11, Util.Polar(srt11, drm1, drm2, cdst)); srt13 = CRS_DST_PNT(drm3, drm4, srt12, vec32, wdst, uiapp, doc); srt14 = EX1_NEA_POINT(srt11, srt12, srt13, OrgPtch, uiapp, doc); srt15 = CRS_DST_PNT(drm1, drm2, srt14, vec23, OrgPtch, uiapp, doc); srt16 = EX1_NEA_POINT(srt11, srt14, srt15, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt15, srt16); dst_chk = srt15.DistanceTo(srt21); srt00 = srt16; srt11_1 = CRS_DST_PNT(trm2, trm3, srt11, vec14, OrgPtch + wdst, uiapp, doc); srt12_1 = CRS_DST_PNT(trm1, trm2, srt11_1, (trm3 - trm2).Normalize(), OrgPtch + (rem12 * 0.5), uiapp, doc); srt13_1 = GetIntersectionPoint(drm3, drm4, srt12_1, Util.Polar(srt12_1, drm2, drm3, cdst)); app1.Add(srt13_1); app1.Add(srt12_1); app1.Add(srt11_1); app1.Add(srt11); app1.Add(srt12); app1.Add(srt13); app1.Add(srt14); app1.Add(srt15); bool endFlg1 = true, endFlg2 = true; int rep = 4; //두번째 코일라인을 작도하기 위해 각 점들을 구함 orgRm1 = srt12_1; orgRm2 = srt11_1; orgRm3 = srt11; orgRm4 = GetIntersectionPoint(srt12_1, srt13_1, srt11, Util.Polar(srt11, drm1, drm2, cdst)); while (endFlg2) { if (rep == 4) app1.Add(srt16); if (rep % 4 == 1) { srt00 = EX1_NEA_POINT(srt11, srt16, srt00, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt00, Util.Polar(srt00, drm3, drm4, OrgPtch)); dst01 = srt00.DistanceTo(srt21); if (endFlg1 == false) endFlg2 = false; }//fmod==1 else if (rep % 4 == 2) { srt16 = srt00; srt00 = CRS_DST_PNT(drm1, drm2, srt00, vec23, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt00, Util.Polar(srt00, drm2, drm1, OrgPtch)); dst02 = srt00.DistanceTo(srt21); }//fmod==2 else if (rep % 4 == 3) { srt00 = EX1_NEA_POINT(srt11, srt16, srt00, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt00, Util.Polar(srt00, drm2, drm1, OrgPtch)); dst03 = srt00.DistanceTo(srt21); }//fmod==3 else if (rep % 4 == 0) { srt00 = CRS_DST_PNT(drm3, drm4, srt00, vec32, wdst, uiapp, doc); srt21 = GetIntersectionPoint(drm1, drm4, srt00, Util.Polar(srt00, drm3, drm4, OrgPtch)); dst00 = srt00.DistanceTo(srt21); srt16 = app1.Last(); }//fmod==0 app1.Add(srt00); if (rep % 4 == 0) dst_chk = dst00; else if (rep % 4 == 1) dst_chk = dst01; else if (rep % 4 == 2) dst_chk = dst02; else if (rep % 4 == 3) dst_chk = dst03; var CvtVal = Unit.FeetToMM(Math.Abs(dst_chk - (OrgPtch * 3))); if (dst_chk == dst01 || dst_chk < (OrgPtch * 3)) { if (dst_chk < (OrgPtch * 3) || CvtVal < 0.01) endFlg1 = false; } if (dst_chk == dst02 || dst_chk < (OrgPtch * 3)) { if (dst_chk < (OrgPtch * 3) || CvtVal < 0.01) endFlg1 = false; } rep++; }//while end app1.RemoveAt(app1.Count() - 1); return app1; } //서브메인 //2020-10-29 선형만 작도되고 파이프 작도되지 않는 현상 수정. public void Exceed_Excoil1(XYZ rm1, XYZ rm2, XYZ rm3, XYZ rm4, UIApplication uiapp, Document doc, double coilDia,PipeType CoilType, PipingSystemType CoilSysType, double offset) { XYZ trm1 = null, trm2 = null, trm3 = null, trm4 = null, pet1 = null, pet11 = null; List PntLst = new List(); XYZ vec12, vec23, vec34, vec41; double dst12, dst23, dst34, dst41, rem12, rem34, rem1, InNum12, InNum34, InNum, wpch12, wpch21, wpch23, wpch32, wpch34, wpch43, wpch41, wpch14; trm1 = rm1; trm2 = rm2; trm3 = rm3; trm4 = rm4;//존이 2개 이상일 경우만 포인트 대체 rm1 = Util.Polar(trm3, trm3, trm4, trm3.DistanceTo(trm4) * 0.6); rm2 = GetIntersectionPoint(trm1, trm2, rm1, Util.Polar(rm1, trm3, trm2, cdst)); rm3 = trm1; 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(); //나머지 rem12 = dst12 % cdst; rem34 = dst34 % cdst; if (dst12 > dst34) rem1 = rem34; else rem1 = rem12; //라인수 InNum12 = Math.Floor(Unit.FeetToMM(dst12 - rem1) / Unit.FeetToMM(cdst)); InNum34 = Math.Floor(Unit.FeetToMM(dst34 - rem1) / Unit.FeetToMM(cdst)); if (dst12 > dst34) InNum = InNum34; else InNum = InNum12; if (InNum % 2 == 0)//라인수가 짝수인 경우만 1을 빼고 홀수이면 그대로 적용하면 실제 거리가 나온다. { InNum--; InNum12--; InNum34--; rem1 = rem1 + cdst; rem12 = rem12 + cdst; rem34 = rem34 + cdst; } if (wdst * 2 > rem1)//벽과의 최소간격보다 나머지가 작은 경우 //wdst2 -> wdst 변경//2020-10-29 { if (InNum % 2 == 0) { rem1 = rem1 + cdst; rem12 = rem12 + cdst; rem34 = rem34 + cdst; InNum--; InNum12--; InNum34--;//코일수가 짝수이면 피치의 한배를 뺀다. } else { rem1 = rem1 + (cdst * 2); rem12 = rem12 + (cdst * 2); rem34 = rem34 + (cdst * 2); InNum = InNum - 2; InNum12 = InNum12 - 2; InNum34 = InNum34 - 2;//코일수가 짝수이면 피치의 두배를 뺀다. } if (InNum % 2 == 0) { rem1 = rem1 + cdst; rem12 = rem12 + cdst; rem34 = rem34 + cdst; InNum--; InNum12--; InNum34--;//벽과의 최소간격보다 나머지가 작은 경우 1를 빼서 작수로 맞춘다. } } rm2 = Util.Polar(rm2, rm2, rm1, (rem1 * 0.5) + (cdst * 4)); rm3 = GetIntersectionPoint(trm1, trm4, rm2, Util.Polar(rm2, trm2, trm1, cdst)); wpch12 = rem12 * 0.5; wpch21 = rem12 * 0.5; wpch23 = wdst; wpch32 = wdst;//각 벽과 외기1 코일의 간격을 설정 wpch34 = rem34 * 0.5; wpch43 = rem34 * 0.5; wpch41 = wdst; wpch14 = wdst; PntLst = Excd_BAND_DRW_PNT(rm1, rm2, rm3, rm4, 0, rem12, trm1, trm2, trm3, trm4, uiapp, doc); //PntLst = PntLst.reverse(); //pet1 = PntLst.at(1); //m_Draw.pyosi(pet1);AfxMessageBox(_T("pet1")); //PntLst = PntLst.reverse(); pet1 = PntLst.Last(); pet11 = CRS_DST_PNT(trm3, trm4, pet1, (trm1 - trm4).Normalize(), rem12 * 0.5, uiapp, doc); //m_Draw.pyosi(pet11);AfxMessageBox(_T("pet11")); PntLst.Add(pet11);//점이 겹치는부분때문에 fillet이 안되서 제거 pet11 = CRS_DST_PNT(trm2, trm3, pet11, (trm4 - trm3).Normalize(), wdst, uiapp, doc); //m_Draw.pyosi(pet11);AfxMessageBox(_T("pet11")); PntLst.Add(pet11); pet11 = CRS_DST_PNT(trm1, trm2, pet11, (trm3 - trm2).Normalize(), rem12 * 0.5, uiapp, doc); //m_Draw.pyosi(pet11);AfxMessageBox(_T("pet11")); PntLst.Add(pet11); pet11 = GetIntersectionPoint(trm1, trm4, pet11, Util.Polar(pet11, rm2, rm3, cdst)); PntLst.Add(pet11); List newPntLst = PtsElevation(PntLst, offset); if (newPntLst == null) return; //m_Draw.DrawPLine(PntLst, 0.0,pid); List pipeElem = new List(); using (Transaction transaction = new Transaction(doc)) { transaction.Start("Start"); Autodesk.Revit.DB.View view = doc.ActiveView; for (int i = 0; i < newPntLst.Count() - 1; i++) { var newLine = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), newPntLst.ElementAt(i), newPntLst.ElementAt(i + 1)); pipeElem.Add(newLine); } CreatePipe1(uidoc, doc, pipeElem, coilDia, CoilType, CoilSysType); transaction.Commit(); } //List resElem = new List(); //var tot_coildst = EX1_VRT_PL_DRW(PntLst, uiapp, doc, resElem); //TaskDialog.Show("결과", "첫번째 코일 길이 : " + Math.Round(tot_coildst, 1)); PntLst.Clear();//array 지움 PntLst = Excd_BAND_DRW_PNT2(orgRm1, orgRm2, orgRm3, orgRm4, 0, rem12, trm1, trm2, trm3, trm4, uiapp, doc); PntLst.RemoveAt(PntLst.Count() - 1); PntLst.RemoveAt(PntLst.Count() - 1);//마지막점부터 2개를 지운다. pet1 = PntLst.Last(); pet11 = GetIntersectionPoint(trm1, trm4, pet1, Util.Polar(pet1, trm2, trm1, cdst)); PntLst.Add(pet11); newPntLst.Clear(); newPntLst = PtsElevation(PntLst, offset); if (newPntLst == null) return; pipeElem.Clear(); using (Transaction transaction = new Transaction(doc)) { transaction.Start("Start"); Autodesk.Revit.DB.View view = doc.ActiveView; for (int i = 0; i < newPntLst.Count() - 1; i++) { var newLine = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), newPntLst.ElementAt(i), newPntLst.ElementAt(i + 1)); pipeElem.Add(newLine); } CreatePipe1(uidoc, doc, pipeElem, coilDia, CoilType, CoilSysType); transaction.Commit(); } //tot_coildst = EX1_VRT_PL_DRW(PntLst, uiapp, doc, resElem); //TaskDialog.Show("결과", "두번째 코일 길이 : " + Math.Round(tot_coildst, 1)); } public double EX1_VRT_PL_DRW(List APP, UIApplication uiapp, Document doc, List lst_elements) { Autodesk.Revit.DB.View view = doc.ActiveView; double total_dst = 0, m_dst = 0; using (Transaction transaction = new Transaction(doc)) { transaction.Start("Start"); for (int i = 0; i < APP.Count() - 1; i++) { Element newLine = Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), APP[i], APP[i + 1]); m_dst = APP[i].DistanceTo(APP[i + 1]); total_dst = total_dst + m_dst; lst_elements.Add(newLine); } transaction.Commit(); } return total_dst; } public List EX1_BAND_DRW_PNT(XYZ rm1, XYZ rm2, XYZ rm3, XYZ rm4, int wyn, double rem12, XYZ trm1, XYZ trm2, XYZ trm3, UIApplication uiapp, Document doc) { double dst00, dst01, dst02, dst03, dst12, dst23, dst34, dst_chk; XYZ vec12, vec21, vec23, vec32, vec41, vec14, vecRM, plrpt; XYZ srt11 = null, srt12 = null, srt13 = null, srt14 = null, srt15 = null, srt16 = null, srt21 = null , srt00 = null, srt01 = null, srt02 = null, srt03 = null, srt04 = null, IntersPt = null; List app1 = new List(); if (welNum > 0) ptch = (ptch * 0.5); dst00 = rm1.DistanceTo(rm2); dst01 = rm1.DistanceTo(rm2); dst02 = rm1.DistanceTo(rm2); dst03 = rm1.DistanceTo(rm2); //비교할 거리 초기화 //var distMM = Unit.CovertFromAPI(DisplayUnitType.DUT_MILLIMETERS, rm1.DistanceTo(rm2)); if (dst00 > cdst * 1.5) { vec12 = (rm2 - rm1).Normalize(); vec21 = (rm1 - rm2).Normalize(); vec23 = (rm3 - rm2).Normalize(); vec32 = (rm2 - rm3).Normalize(); vec34 = (rm4 - rm3).Normalize(); vec43 = (rm3 - rm4).Normalize(); vec41 = (rm1 - rm4).Normalize(); vec14 = (rm4 - rm1).Normalize(); dst12 = rm1.DistanceTo(rm2); dst23 = rm2.DistanceTo(rm3); dst34 = rm3.DistanceTo(rm4); if (wyn == 0) { srt11 = Util.Polar(rm1, vec23, wdst); srt12 = CRS_DST_PNT(rm2, rm3, srt11, vec21, rem12 * 0.5, uiapp, doc); } else { srt11 = Util.Polar(rm1, vec23, OrgPtch); srt12 = CRS_DST_PNT(rm2, rm3, srt11, vec21, OrgPtch, uiapp, doc); } srt13 = CRS_DST_PNT(rm3, rm4, srt12, vec32, wdst, uiapp, doc); if (welNum > 0) srt14 = EX1_NEA_POINT(srt11, srt12, srt13, ptch, uiapp, doc); else srt14 = EX1_NEA_POINT(srt11, srt12, srt13, OrgPtch, uiapp, doc); if (wyn == 0) srt15 = CRS_DST_PNT(rm1, rm2, srt14, vec23, wdst + OrgPtch, uiapp, doc); else srt15 = CRS_DST_PNT(rm1, rm2, srt14, vec23, OrgPtch * 2, uiapp, doc); if (welNum > 0) srt16 = EX1_NEA_POINT(srt11, srt14, srt15, ptch, uiapp, doc); else srt16 = EX1_NEA_POINT(srt11, srt14, srt15, OrgPtch, uiapp, doc); //Pyosi(uiapp, doc, srt16); //TaskDialog.Show("t", "16"); srt21 = GetIntersectionPoint(rm1, rm4, srt15, srt16); dst_chk = srt15.DistanceTo(srt21); srt00 = srt16; app1.Add(srt11); app1.Add(srt12); app1.Add(srt13); app1.Add(srt14); app1.Add(srt15); int rep = 4, exFlg = 2; bool endFlg1 = true, endFlg2 = true; if (welNum > 0) { if (exFlg >= welNum) ptch = OrgPtch; } while (endFlg2) { if (rep == 4) app1.Add(srt16); if (rep % 4 == 1) { if (welNum > 0) srt00 = EX1_NEA_POINT(srt11, srt16, srt00, ptch, uiapp, doc); else srt00 = EX1_NEA_POINT(srt11, srt16, srt00, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(rm1, rm4, srt00, Util.Polar(srt00, rm3, rm4, OrgPtch)); dst01 = srt00.DistanceTo(srt21); }//(rep % 4 == 1) else if (rep % 4 == 2) { srt16 = srt00; if (wyn == 0) srt00 = CRS_DST_PNT(rm1, rm2, srt00, vec23, wdst + OrgPtch, uiapp, doc); else srt00 = CRS_DST_PNT(rm1, rm2, srt00, vec23, OrgPtch * 2, uiapp, doc); srt21 = GetIntersectionPoint(rm1, rm4, srt00, Util.Polar(srt00, rm2, rm1, OrgPtch)); dst02 = srt00.DistanceTo(srt21); exFlg++; if (endFlg1 == false) endFlg2 = false; }//(rep % 4 == 2) else if (rep % 4 == 3) { if (welNum > 0) srt00 = EX1_NEA_POINT(srt11, srt16, srt00, ptch, uiapp, doc); else srt00 = EX1_NEA_POINT(srt11, srt16, srt00, OrgPtch, uiapp, doc); srt21 = GetIntersectionPoint(rm1, rm4, srt00, Util.Polar(srt00, rm2, rm1, OrgPtch)); dst03 = srt00.DistanceTo(srt21); }//(rep % 4 == 3) else if (rep % 4 == 0) { srt00 = CRS_DST_PNT(rm3, rm4, srt00, vec32, wdst, uiapp, doc); srt21 = GetIntersectionPoint(rm1, rm4, srt00, Util.Polar(srt00, rm3, rm4, OrgPtch)); dst00 = srt00.DistanceTo(srt21); srt16 = app1.Last(); exFlg++; }//(rep % 4 == 0) app1.Add(srt00); //최소값 if (rep % 4 == 0) dst_chk = dst00; else if (rep % 4 == 1) dst_chk = dst01; else if (rep % 4 == 2) dst_chk = dst02; else if (rep % 4 == 3) dst_chk = dst03; var mm_dst_chk = Unit.FeetToMM(dst_chk); var mm_dst01 = Unit.FeetToMM(dst01); var mm_dst02 = Unit.FeetToMM(dst02); if (Math.Abs(mm_dst_chk-Math.Floor(mm_dst01)) < 0.0001 || mm_dst_chk < Unit.FeetToMM(OrgPtch * 3)) { if (mm_dst_chk < Unit.FeetToMM(OrgPtch * 3) || Math.Abs(mm_dst_chk - Unit.FeetToMM(OrgPtch * 3)) < 0.01) endFlg1 = false; } else if (Math.Abs(mm_dst_chk - Math.Floor(mm_dst02)) < 0.0001 || mm_dst_chk < Unit.FeetToMM(OrgPtch * 3)) { if (mm_dst_chk < Unit.FeetToMM(OrgPtch * 3) || Math.Abs(mm_dst_chk - Unit.FeetToMM(OrgPtch * 3)) < 0.01) endFlg1 = false; } rep++; if (welNum > 0) { if (exFlg == welNum && drawFlg == true)//외기라인수와 코일 라인수가 같고 작도플래그가 참일 떄 { OrgPt0 = app1.ElementAt(0); OrgPtList.AddRange(app1); app1.Clear(); app1.Add(srt00);//두번째 리스트에 추가해주어야 함 drawFlg = false; welNum = 0; } drawFlg = false;//라인수가 없으면 작도플래그도 NULL설정함. } if (welNum > 0) { if (exFlg >= welNum) ptch = OrgPtch;//외기 라인수에 따라 피치값 원위치 } //testcnt++; //if (testcnt == 10) break; }//while end if (welNum > 0) srt01 = EX1_NEA_POINT(srt11, srt16, srt00, ptch, uiapp, doc); else srt01 = EX1_NEA_POINT(srt11, srt16, srt00, OrgPtch, uiapp, doc); app1.Add(srt01); srt02 = CRS_DST_PNT(rm3, rm4, srt01, vec32, wdst, uiapp, doc); srt16 = app1.Last(); app1.Add(srt02); if (welNum > 0) srt03 = EX1_NEA_POINT(srt11, srt16, srt02, ptch, uiapp, doc); else srt03 = EX1_NEA_POINT(srt11, srt16, srt02, OrgPtch, uiapp, doc); app1.Add(srt03); if (wyn == 0) srt04 = CRS_DST_PNT(rm1, rm2, srt03, vec23, wdst + OrgPtch, uiapp, doc); else srt04 = CRS_DST_PNT(rm1, rm2, srt03, vec23, OrgPtch * 2, uiapp, doc); app1.Add(srt04); double dst1112 = srt11.DistanceTo(srt12), dst0213 = srt02.DistanceTo(srt13), Length; Length = app1.Count(); if (dst1112 < dst0213) { app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); } else if (Unit.FeetToMM(Math.Abs(dst1112 - dst0213)) < 0.1) { app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); } if (Unit.FeetToMM(dst0213) < Unit.FeetToMM(cdst * 2) + 1) { app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); app1.RemoveAt(app1.Count() - 1); } } else { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); return app1; } IntersPt = GetIntersectionPoint(rm1, rm2, trm2, trm3); if (wyn > 1) { if (trm1.DistanceTo(trm2) < rm1.DistanceTo(IntersPt)) { TaskDialog.Show("오류", "지정된 방의 크기가 작아서 작도할 수 없습니다."); return null; } } return app1; } public XYZ EX1_NEA_POINT(XYZ nPt1, XYZ nPt2, XYZ nPt3, double dstNum, UIApplication uiapp, Document doc) { XYZ pt1, pt2, rtnPt, vecPt; double dst1, dst2; double pi = Math.PI; vecPt = (nPt3 - nPt2).Normalize(); vecPt = Util.RotateVector(vecPt, pi * 0.5); //var tranRot = Transform.CreateRotation(XYZ.BasisZ, pi * 0.5); //vecPt = tranRot.OfVector(vecPt); pt1 = nPt3 + vecPt * dstNum; vecPt = (nPt3 - nPt2).Normalize(); vecPt = Util.RotateVector(vecPt, pi * 1.5); //tranRot = Transform.CreateRotation(XYZ.BasisZ, pi * 1.5); //vecPt = tranRot.OfVector(vecPt); pt2 = nPt3 + vecPt * dstNum; dst1 = nPt1.DistanceTo(pt1); dst2 = nPt1.DistanceTo(pt2); var cvtVal = Math.Abs(Unit.FeetToMM(dst1 - dst2)); if (dst1 > dst2 || cvtVal < 0.01) rtnPt = pt2; else rtnPt = pt1; return rtnPt; } 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 FeetToMM(XYZ spt, XYZ ept) { double res = 0; res = System.Math.Round(Unit.FeetToMM(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); 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)).FirstOrDefault() as PipeType; //FilteredElementCollector collector = new FilteredElementCollector(document); //ICollection collection = collector.OfClass(typeof(PipeType)).ToElements(); //PipeType pipeType = null; //foreach (Element elem in collection) //{ // if(elem is PipeType) // { // pipeType = elem as PipeType; // // } //} //Level level = new FilteredElementCollector(document).OfClass(typeof(Level)).First() as Level; Level level = document.ActiveView.GenLevel; //FilteredElementCollector sysCollector = new FilteredElementCollector(document); ////sysCollector.OfClass(typeof(PipingSystemType)); //sysCollector.OfCategory(BuiltInCategory.OST_PipingSystem); //ElementId pipeSysTypeId = sysCollector.FirstElementId(); //bool flag = true; // Extract all pipe system types // 1-2) 변수선언 Pipe newpipe = 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); } //MessageBox.Show("1123"); //GeometryElement geometry = elementlist.ElementAt(i).get_Geometry(new Options()); //geometryElements.Add(geometry); } // 1-4) 트랜젝션 실행 //using (Transaction trans = new Transaction(document)) //{ try { //trans.Start("Create pipe"); // 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) { //Line line = cur as Line; XYZ start = cur.GetEndPoint(0); XYZ 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 (Exception e) { //MessageBox.Show("" + e); } } //trans.Commit(); } catch (Exception e) { //MessageBox.Show("" + e); //MessageBox.Show("Pipe 간의 각도가 너무 크거나 작습니다. \n조정 후 다시 시도해주세요"); //trans.RollBack(); } // pipe와 겹치는 line 삭제하기 foreach (Element element in elementlist) { if (element == null) continue; ElementId elementId = element.Id; document.Delete(elementId); } //} } //포인트들 현재 레벨의 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; } } }