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; namespace KMBIM { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] class TrimSpacing : 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; double m_TrimDist = 0; List m_ElemLst = new List(); try { Form_TrimSpacing dlg = new Form_TrimSpacing(); dlg.ShowDialog(); if (dlg.DialogResult == DialogResult.Cancel) return Result.Cancelled; //대화상자 값 가져오기 m_TrimDist = Math.Round(dlg.m_trimDist, 4); IList pickrefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, new SelectionFilter(), "절단할 배관 선택 : "); if (pickrefs == null) return Result.Cancelled; foreach (Reference refer in pickrefs) { ElementId id = refer.ElementId; Element elem = doc.GetElement(id); m_ElemLst.Add(elem); } int NotDrawCnt = 0; foreach (Element elem in m_ElemLst) { List m_DivPtLst = new List(); XYZ sp = null, ep = null; XYZ FlowVec = null, ReverseVec = null; if (elem is Pipe) { Util.GetStartEndPoint(elem as Pipe, ref sp, ref ep); Line pipeline = ((elem as Pipe).Location as LocationCurve).Curve as Line; FlowVec = (ep - sp).Normalize(); ReverseVec = (sp - ep).Normalize(); int Cnt = 1; while (true) { XYZ trimPt = Util.Polar(sp, FlowVec, Unit.MMToFeet(m_TrimDist * 1000 * Cnt)); //Util.Pyosi(doc, trimPt,1); //MessageBox.Show("1"); IntersectionResult interRes = pipeline.Project(trimPt); XYZ interResPt = interRes.XYZPoint; //Util.Pyosi(doc, interResPt, 1); //MessageBox.Show("1"); //interRes가 선의 끝점부터 if (interResPt.IsAlmostEqualTo(trimPt, Unit.MMToFeet(0.01))) m_DivPtLst.Add(interResPt); else break; Cnt++; }//while end } using (Transaction trans = new Transaction(doc)) { trans.Start("1"); Pipe mainPipe = elem as Pipe; foreach (XYZ divPt in m_DivPtLst) { //파이프 자르기 List ElemIDLst = Util.DivideElement(doc, mainPipe, divPt); //List famconlst = Util.GetElementConnectors(newFamily); List pipe1conlst = Util.GetElementConnectors(doc.GetElement(ElemIDLst.First())); List pipe2conlst = Util.GetElementConnectors(doc.GetElement(ElemIDLst[1])); //자른 객체의 겹치는 커넥터에 유니온 피팅 foreach (Connector con1 in pipe1conlst) { foreach (Connector con2 in pipe2conlst) { if (con1.Origin.IsAlmostEqualTo(con2.Origin, Unit.MMToFeet(0.01))) { //유니온 피팅 FamilyInstance famUnion = doc.Create.NewUnionFitting(con1, con2); List famConLst = Util.GetElementConnectors(famUnion); doc.Regenerate(); //Connector Fsp = null, Fep = null, Ssp = null, Sep = null; //Util.GetStartEndConnector(doc.GetElement(ElemIDLst.First()) as Pipe, ref Fsp, ref Fep); //Util.GetStartEndConnector(doc.GetElement(ElemIDLst[1]) as Pipe, ref Ssp, ref Sep); ////유니온 장착 후 앞쪽 파이프 길이가 지정한 길이가 아니면 유니온 옮김 //if (Math.Abs(Fsp.Origin.DistanceTo(Fep.Origin) - Unit.MMToFeet(m_TrimDist * 1000)) > Unit.MMToFeet(0.01)) //{ // if (Fsp.Origin.DistanceTo(Fep.Origin) - Unit.MMToFeet(m_TrimDist * 1000) < 0) // { // Transform familyTrans = famUnion.GetTransform(); // /*유니온 두개의 커넥터 사이기 길이 반만큼 이동해야 하기 때문에 // 뒤쪽 파이프 시작점으로 이동*/ // XYZ translation = Ssp.Origin - familyTrans.Origin; // ElementTransformUtils.MoveElement(doc, famUnion.Id, translation); // doc.Regenerate(); // } //} if (famUnion == null) NotDrawCnt++; break; } } } //나뉜 파이프 리스트에서 기준 파이프로 변경 mainPipe = doc.GetElement(ElemIDLst[1]) as Pipe; } trans.Commit(); } }//foreach end if (NotDrawCnt > 0) MessageBox.Show("작도 실패 : " + NotDrawCnt + " 개", "결과"); } catch (Exception e) { MessageBox.Show("" + e); } return Result.Succeeded; } public class SelectionFilter : ISelectionFilter { public bool AllowElement(Element element) { if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeCurves) { return true; } return false; } public bool AllowReference(Reference refer, XYZ point) { return false; } } } }