using System; using Autodesk.Revit.UI; using Autodesk.Revit.DB; using System.Collections.Generic; using System.Windows.Forms; using System.Linq; using Autodesk.Revit.UI.Selection; using Autodesk.Revit.DB.Plumbing; using KDCS.Utils; using Autodesk.Revit.DB.Structure; using KMBIM.Revit.Tools.Cmd.SprinklerConnect; using KMBIM.Revit.Tools; using View = Autodesk.Revit.DB.View; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Electrical; namespace KMBIM { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class Stretch : IExternalCommand { UIApplication uiapp; UIDocument uidoc; Autodesk.Revit.DB.Document doc; Autodesk.Revit.Creation.Application creApp; Autodesk.Revit.Creation.Document creDoc; Autodesk.Revit.UI.ExternalCommandData m_commandData; public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { m_commandData = commandData; uiapp = commandData.Application; uidoc = uiapp.ActiveUIDocument; doc = uidoc.Document; creApp = uiapp.Application.Create; creDoc = doc.Create; try { //if (!WorkMain.GetInstance().IsValid) return Autodesk.Rev it.UI.Result.Succeeded; //PickedBox pickedBox = commandData.Application.ActiveUIDocument.Selection.PickBox(PickBoxStyle.Crossing); IList pickRefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(ObjectType.Element, new SelectPipeDuct(), "신축할 설비요소 선택 :"); List ElemLst = new List(); foreach(Reference refer in pickRefs) { ElemLst.Add(doc.GetElement(refer)); } XYZ Dirpt; using (Transaction t = new Transaction(doc)) { t.Start("Test Transaction"); SketchPlane sp = SketchPlane.Create(doc, Plane.CreateByNormalAndOrigin( doc.ActiveView.ViewDirection, doc.ActiveView.Origin)); doc.ActiveView.SketchPlane = sp; // Finally, we are able to PickPoint() Dirpt = uidoc.Selection.PickPoint(); // Don't forget to clean up doc.Delete(sp.Id); t.Commit(); } //XYZ Dirpt = commandData.Application.ActiveUIDocument.Selection.PickPoint("기준점 지정 : "); //XYZ Tranpt = commandData.Application.ActiveUIDocument.Selection.PickPoint("변경할 위치 점 지정 : "); //스트레치 길이 //double m_StretchDist = Dirpt.DistanceTo(Tranpt); // XYZ firstSp = null, firstEp = null; foreach(Element elem in ElemLst) { if (elem is Pipe) { Pipe FirstPipe = ElemLst.First() as Pipe; Util.GetStartEndPoint(FirstPipe, ref firstSp, ref firstEp); break; } else if (elem is Duct) { Duct FirstDuct = ElemLst.First() as Duct; Util.GetStartEndPoint(FirstDuct, ref firstSp, ref firstEp); break; } else if (elem is FlexPipe) { FlexPipe FirstFlexPipe = ElemLst.First() as FlexPipe; Util.GetStartEndPoint(FirstFlexPipe, ref firstSp, ref firstEp); break; } else if (elem is FlexDuct) { FlexDuct FirstFlexDuct = ElemLst.First() as FlexDuct; Util.GetStartEndPoint(FirstFlexDuct, ref firstSp, ref firstEp); break; } else if (elem is CableTray) { CableTray FirstTray = ElemLst.First() as CableTray; Util.GetStartEndPoint(FirstTray, ref firstSp, ref firstEp); break; } else if (elem is Conduit) { Conduit FirstConduit = ElemLst.First() as Conduit; Util.GetStartEndPoint(FirstConduit, ref firstSp, ref firstEp); break; } } XYZ RotVec1 = Util.RotateVector(firstSp, firstEp, Unit.MMToFeet(90)); XYZ RotVec2 = Util.RotateVector(firstSp, firstEp, Unit.MMToFeet(-90)); XYZ DirLinePt1 = Util.Polar(Dirpt, RotVec1, 100); XYZ DirLinePt2 = Util.Polar(Dirpt, RotVec2, 100); //연결되지 않은 커넥터 리스트 구하기 List m_CloseConLst = new List(); foreach(Element elem in ElemLst) { Connector closeCon = ClosestConnect(Dirpt, elem); if (closeCon.IsConnected == true) continue; m_CloseConLst.Add(closeCon); } using(Transaction trans = new Transaction(doc)) { trans.Start("1"); foreach (Connector con in m_CloseConLst) { Connector otherCon = Util.GetOtherConnector(con); //기준 파이프로 가상선 생성 XYZ VirtualSpt = Util.Polar(con.Origin, (con.Origin - otherCon.Origin).Normalize(), 100); XYZ VirtualEpt = Util.Polar(con.Origin, (otherCon.Origin - con.Origin).Normalize(), 100); Line VirtualLine = Line.CreateBound(VirtualSpt, VirtualEpt); //기준 점 파이프 가상선 교차점 찾기 IntersectionResult interRes = VirtualLine.Project(Dirpt); XYZ ElemDirPt = interRes.XYZPoint; //Util.Pyosi(doc, ElemDirPt, 0);o con.Origin = ElemDirPt; //MessageBox.Show("1"); } trans.Commit(); } } catch (Exception) { } return Result.Succeeded; } //기준점으로부터 가까운 커넥터 구하기. public Connector ClosestConnect(XYZ Dirpt,Element elem) { List ConLst = Util.GetElementConnectors(elem); double dist = double.MaxValue; Connector CloseCon = null; foreach (Connector con in ConLst) { XYZ conZ0 = new XYZ(con.Origin.X, con.Origin.Y, 0); if (Dirpt.DistanceTo(conZ0) <= dist) { CloseCon = con; dist = Dirpt.DistanceTo(conZ0); } } return CloseCon; } } public class SelectPipeDuct : ISelectionFilter { public bool AllowElement(Element element) { if (element.Category == null) return false; if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeCurves || element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctCurves || element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_CableTray || element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Conduit || element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_FlexPipeCurves || element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_FlexDuctCurves) { return true; } return false; } public bool AllowReference(Reference refer, XYZ point) { return false; } } }