317 lines
14 KiB
C#
317 lines
14 KiB
C#
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;
|
|
|
|
|
|
namespace KMBIM
|
|
{
|
|
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
|
class PipeTrimSpacing : 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)
|
|
{
|
|
if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
|
|
m_commandData = commandData;
|
|
uiapp = commandData.Application;
|
|
uidoc = uiapp.ActiveUIDocument;
|
|
doc = uidoc.Document;
|
|
creApp = uiapp.Application.Create;
|
|
creDoc = doc.Create;
|
|
|
|
double m_TrimDist = 0;
|
|
|
|
|
|
List<Element> m_ElemLst = new List<Element>();
|
|
|
|
|
|
try
|
|
{
|
|
Form_TrimSpacing dlg = new Form_TrimSpacing();
|
|
dlg.m_label = "m";
|
|
dlg.m_trimDist = 6;
|
|
dlg.ShowDialog();
|
|
if (dlg.DialogResult == DialogResult.Cancel) return Result.Cancelled;
|
|
//대화상자 값 가져오기
|
|
m_TrimDist = Math.Round(dlg.m_trimDist * 1000, 4);
|
|
|
|
|
|
//IList<Reference> pickrefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, new SelectionFilter(), "절단할 배관 선택 : ");
|
|
//if (pickrefs == null) return Result.Cancelled;
|
|
|
|
while (true)
|
|
{
|
|
Reference pickRef = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new SelectionFilter(), "절단할 배관 선택 : ");
|
|
//Util.Pyosi(doc, pickRef.GlobalPoint,1);
|
|
//사용자가 PickObject로 객체 선택할 때 찍은 점
|
|
XYZ Globalpt = pickRef.GlobalPoint;
|
|
if (pickRef == null) return Result.Cancelled;
|
|
|
|
Element elem = doc.GetElement(pickRef.ElementId);
|
|
|
|
using (Transaction trans = new Transaction(doc))
|
|
{
|
|
trans.Start("cutting");
|
|
|
|
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;
|
|
|
|
bool ChgSpEp = false;
|
|
//끝점과 가까우면 시작 끝점 바꾸기
|
|
if(Globalpt.DistanceTo(sp) > Globalpt.DistanceTo(ep))
|
|
{
|
|
XYZ PassPt = sp;
|
|
sp = ep;
|
|
ep = PassPt;
|
|
ChgSpEp = true;
|
|
}
|
|
|
|
FlowVec = (ep - sp).Normalize();
|
|
ReverseVec = (sp - ep).Normalize();
|
|
|
|
XYZ DirPt = sp;
|
|
Pipe MainPipe = elem as Pipe;
|
|
|
|
double UnionLength = 0;
|
|
while (true)
|
|
{
|
|
//자를 기준점
|
|
XYZ trimPt = Util.Polar(DirPt, FlowVec, Unit.MMToFeet(m_TrimDist));
|
|
//Util.Pyosi(doc, trimPt, 0);
|
|
//자를 기준점이 파이프를 넘어간 경우 작도 중지
|
|
Line divPipeLine = (MainPipe.Location as LocationCurve).Curve as Line;
|
|
XYZ onLinePt = Util.GetPointOnLine(divPipeLine, trimPt);
|
|
|
|
if (onLinePt.IsAlmostEqualTo(divPipeLine.GetEndPoint(0))
|
|
|| onLinePt.IsAlmostEqualTo(divPipeLine.GetEndPoint(1)))
|
|
break;
|
|
|
|
IntersectionResult interRes = pipeline.Project(trimPt);
|
|
XYZ interResPt = interRes.XYZPoint;
|
|
|
|
//첫번째 유니온삽입 시 유니온 길이를 알 수 없어 50으로 정함
|
|
//두번째부터는 첫번째 넣은 유니온 길이를 구해 그 값보다 작으면 작도 X
|
|
//if (trimPt.DistanceTo(ep) < Unit.MMToFeet(10)) break;
|
|
if (UnionLength > 0)
|
|
{
|
|
if (trimPt.DistanceTo(ep) < UnionLength) break;
|
|
}
|
|
else
|
|
{
|
|
if (trimPt.DistanceTo(ep) < Unit.MMToFeet(50)) break;
|
|
}
|
|
|
|
List<ElementId> ElemIDLst = new List<ElementId>();
|
|
|
|
//파이프 자르기
|
|
ElemIDLst = Util.DivideElement(doc, MainPipe, trimPt);
|
|
|
|
if (ElemIDLst.Count() == 0) break;
|
|
//Util.Pyosi(doc, trimPt, 0);
|
|
DirPt = trimPt;
|
|
doc.Regenerate();
|
|
|
|
if (ChgSpEp == true)
|
|
{
|
|
MainPipe = doc.GetElement(ElemIDLst[0]) as Pipe;
|
|
}
|
|
|
|
List<Connector> pipe1conlst = Util.GetElementConnectors(doc.GetElement(ElemIDLst[0]));
|
|
List<Connector> 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<Connector> UnionConLst = Util.GetElementConnectors(famUnion);
|
|
if (UnionConLst.Count == 2)
|
|
{
|
|
UnionLength = UnionConLst[0].Origin.DistanceTo(UnionConLst[1].Origin);
|
|
}
|
|
//Util.Pyosi(doc, con1.Origin, 0);
|
|
//DirPt = con1.Origin;
|
|
doc.Regenerate();
|
|
|
|
//if (famUnion == null) NotDrawCnt++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}//while end
|
|
|
|
}
|
|
|
|
trans.Commit();
|
|
}
|
|
|
|
|
|
}//while end 파이프 선택 반복문
|
|
|
|
|
|
|
|
|
|
//foreach (Reference refer in pickrefs)
|
|
//{
|
|
// ElementId id = refer.ElementId;
|
|
// Element elem = doc.GetElement(id);
|
|
// m_ElemLst.Add(elem);
|
|
//}
|
|
|
|
//int NotDrawCnt = 0;
|
|
//using(Transaction trans = new Transaction(doc))
|
|
//{
|
|
// trans.Start("cutting");
|
|
//
|
|
// foreach (Element elem in m_ElemLst)
|
|
// {
|
|
// List<XYZ> m_DivPtLst = new List<XYZ>();
|
|
// 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();
|
|
//
|
|
// XYZ DirPt = sp;
|
|
// Pipe mainpipe = elem as Pipe;
|
|
//
|
|
// double UnionLength = 0;
|
|
// while (true)
|
|
// {
|
|
// //자를 기준점
|
|
// XYZ trimPt = Util.Polar(DirPt, FlowVec, Unit.MMToFeet(m_TrimDist));
|
|
//
|
|
// //자를 기준점이 덕트를 넘어간 경우 작도 중지
|
|
// Line divpipeLine = (mainpipe.Location as LocationCurve).Curve as Line;
|
|
// XYZ onLinePt = Util.GetPointOnLine(divpipeLine, trimPt);
|
|
//
|
|
// if (onLinePt.IsAlmostEqualTo(divpipeLine.GetEndPoint(0))
|
|
// || onLinePt.IsAlmostEqualTo(divpipeLine.GetEndPoint(1)))
|
|
// break;
|
|
//
|
|
// IntersectionResult interRes = pipeline.Project(trimPt);
|
|
// XYZ interResPt = interRes.XYZPoint;
|
|
// //첫번째 유니온삽입 시 유니온 길이를 알 수 없어 50으로 정함
|
|
// //두번째부터는 첫번째 넣은 유니온 길이를 구해 그 값보다 작으면 작도 X
|
|
// //if (trimPt.DistanceTo(ep) < Unit.MMToFeet(10)) break;
|
|
// if (UnionLength > 0)
|
|
// {
|
|
// if (trimPt.DistanceTo(ep) < UnionLength) break;
|
|
// }
|
|
// else
|
|
// {
|
|
// if (trimPt.DistanceTo(ep) < Unit.MMToFeet(50)) break;
|
|
// }
|
|
//
|
|
// List<ElementId> ElemIDLst = new List<ElementId>();
|
|
//
|
|
// //파이프 자르기
|
|
// ElemIDLst = Util.DivideElement(doc, mainpipe, trimPt);
|
|
//
|
|
// if (ElemIDLst.Count() == 0) break;
|
|
// //Util.Pyosi(doc, trimPt, 0);
|
|
// DirPt = trimPt;
|
|
// doc.Regenerate();
|
|
//
|
|
//
|
|
// List<Connector> pipe1conlst = Util.GetElementConnectors(doc.GetElement(ElemIDLst[0]));
|
|
// List<Connector> 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<Connector> UnionConLst = Util.GetElementConnectors(famUnion);
|
|
// if (UnionConLst.Count == 2)
|
|
// {
|
|
// UnionLength = UnionConLst[0].Origin.DistanceTo(UnionConLst[1].Origin);
|
|
// }
|
|
// //Util.Pyosi(doc, con1.Origin, 0);
|
|
// //DirPt = con1.Origin;
|
|
// doc.Regenerate();
|
|
//
|
|
// //if (famUnion == null) NotDrawCnt++;
|
|
// break;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// }//while end
|
|
// }
|
|
// }//foreach end
|
|
//
|
|
//
|
|
// trans.Commit();
|
|
//}
|
|
//
|
|
//if (NotDrawCnt > 0)
|
|
// MessageBox.Show("작도 실패 : " + NotDrawCnt + " 개", "결과");
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//MessageBox.Show("" + e);
|
|
}
|
|
|
|
|
|
|
|
return Result.Succeeded;
|
|
}
|
|
|
|
public class SelectionFilter : 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;
|
|
}
|
|
}
|
|
}
|
|
}
|