351 lines
13 KiB
C#
351 lines
13 KiB
C#
using Autodesk.Revit.DB;
|
|
using Autodesk.Revit.UI;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
//using COME4Revit.WinForm;
|
|
using System.Diagnostics;
|
|
using Autodesk.Revit.UI.Selection;
|
|
using Autodesk.Revit.DB.Mechanical;
|
|
using KMBIM.Revit.Tools;
|
|
using KDCS.Utils;
|
|
|
|
namespace KMBIM
|
|
{
|
|
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
|
class DuctConnectT : IExternalCommand
|
|
{
|
|
UIApplication uiapp;
|
|
UIDocument uidoc;
|
|
Document doc;
|
|
Autodesk.Revit.Creation.Application creApp;
|
|
Autodesk.Revit.Creation.Document creDoc;
|
|
|
|
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
|
|
{
|
|
if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
|
|
uiapp = commandData.Application;
|
|
uidoc = uiapp.ActiveUIDocument;
|
|
Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
|
|
doc = uidoc.Document;
|
|
creApp = uiapp.Application.Create;
|
|
creDoc = doc.Create;
|
|
|
|
List<XYZ> MainPtLst = new List<XYZ>();
|
|
List<XYZ> BranchPtLst = new List<XYZ>();
|
|
Element MainElem = null;
|
|
List<Element> m_BranchElemLst = new List<Element>();
|
|
List<Element> m_MainElemLst = new List<Element>();
|
|
|
|
try
|
|
{
|
|
|
|
Reference pickref = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new DuctSelectionFilter());
|
|
if (pickref != null)
|
|
{
|
|
ElementId tt = pickref.ElementId;
|
|
MainElem = doc.GetElement(tt) as Element;
|
|
//MessageBox.Show("메인 : " + MainElem.Name);
|
|
}
|
|
|
|
m_MainElemLst.Add(MainElem);
|
|
|
|
IList<Reference> pickrefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, new DuctSelectionFilter());
|
|
if (pickrefs != null)
|
|
{
|
|
foreach (Reference refer in pickrefs)
|
|
{
|
|
ElementId tt = refer.ElementId;
|
|
Element BranchElem = doc.GetElement(tt) as Element;
|
|
if (MainElem.Id.Compare(BranchElem.Id) == 0) continue;
|
|
m_BranchElemLst.Add(BranchElem);
|
|
//MessageBox.Show("가지 :" + BranchElem);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ElementId divDuctID = null;
|
|
int breakcnt = 0;
|
|
bool b_MainCutTrue = false;
|
|
|
|
using (Transaction trans = new Transaction(doc))
|
|
{
|
|
trans.Start("CreateT");
|
|
try
|
|
{
|
|
while (true)
|
|
{
|
|
foreach (Element mainElem in m_MainElemLst)
|
|
{
|
|
|
|
|
|
foreach (Element BranchElem in m_BranchElemLst)
|
|
{
|
|
divDuctID = CreateDuctT(mainElem, BranchElem, true);
|
|
|
|
if (divDuctID != null)
|
|
{
|
|
m_BranchElemLst.Remove(BranchElem);
|
|
b_MainCutTrue = true;
|
|
break;
|
|
}
|
|
else
|
|
b_MainCutTrue = false;
|
|
|
|
}
|
|
if (b_MainCutTrue == false) break;
|
|
}
|
|
if (divDuctID != null)
|
|
m_MainElemLst.Add(doc.GetElement(divDuctID));
|
|
breakcnt++;
|
|
if (breakcnt > 100) break;
|
|
if (m_BranchElemLst.Count <= 0) break;
|
|
}//while end
|
|
//MessageBox.Show("메인 개수 :" + m_MainElemLst.Count);
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
|
|
trans.Commit();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
|
|
|
|
return Result.Succeeded;
|
|
}
|
|
|
|
//덕트T 연결 메인,가지 교차점 trim 후 Tee 삽입
|
|
public ElementId CreateDuctT(Element main_element, Element branch_element, bool MainDuct_Down)
|
|
{
|
|
ElementId m_divideElemId = null, b_divideElemId = null;
|
|
List<XYZ> mainElemPts = new List<XYZ>();
|
|
List<XYZ> branchElemPts = new List<XYZ>();
|
|
XYZ InterPt, main_InterPt, branch_InterPt;
|
|
|
|
Duct mainDuct = main_element as Duct;
|
|
Duct branchDuct = branch_element as Duct;
|
|
|
|
mainElemPts = GetDuctConnectorPts(mainDuct);
|
|
branchElemPts = GetDuctConnectorPts(branchDuct);
|
|
|
|
InterPt = GetIntersectionPoint(mainElemPts[0], mainElemPts[1], branchElemPts[0], branchElemPts[1]);
|
|
if (InterPt == null) return null;
|
|
|
|
|
|
main_InterPt = new XYZ(InterPt.X, InterPt.Y, mainElemPts[0].Z);
|
|
branch_InterPt = new XYZ(InterPt.X, InterPt.Y, branchElemPts[0].Z);
|
|
|
|
try
|
|
{
|
|
mainDuct = main_element as Duct;
|
|
m_divideElemId = MechanicalUtils.BreakCurve(doc, mainDuct.Id, main_InterPt);
|
|
branchDuct = branch_element as Duct;
|
|
b_divideElemId = MechanicalUtils.BreakCurve(doc, branchDuct.Id, branch_InterPt);
|
|
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
|
|
|
|
//나뉜 메인관이 없을 경우 리턴
|
|
if (m_divideElemId == null) return null;
|
|
|
|
//T연결시 커넥트 3개가 필요하여 메인 가지관 교차점 사이에 파이프 작도
|
|
//잘린 메인id 파이프로 전환
|
|
Duct mainDivide = doc.GetElement(m_divideElemId) as Duct;
|
|
Duct branchDivide = doc.GetElement(b_divideElemId) as Duct;
|
|
Duct HeadDuct = null;
|
|
Level level = new FilteredElementCollector(doc).OfClass(typeof(Level)).First() as Level;
|
|
|
|
//if (main_InterPt.IsAlmostEqualTo(branch_InterPt,0.1)) return null;
|
|
|
|
Parameter mainParam = mainDuct.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
|
|
Parameter branchParam = branchDuct.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
|
|
if(mainParam.AsDouble() < branchParam.AsDouble())
|
|
{
|
|
HeadDuct = Duct.Create(doc, mainDuct.MEPSystem.GetTypeId(), mainDuct.GetTypeId(), level.Id, main_InterPt, branch_InterPt);
|
|
Connector con = HeadDuct.ConnectorManager.Connectors.Cast<Connector>().First();
|
|
con.Width = branchParam.AsDouble();
|
|
mainParam = mainDuct.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
|
|
con.Height = branchParam.AsDouble();
|
|
}
|
|
else
|
|
{
|
|
HeadDuct = Duct.Create(doc, branchDuct.MEPSystem.GetTypeId(), branchDuct.GetTypeId(), level.Id, main_InterPt, branch_InterPt);
|
|
Connector con = HeadDuct.ConnectorManager.Connectors.Cast<Connector>().First();
|
|
con.Width = branchParam.AsDouble();
|
|
branchParam = branchDuct.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
|
|
con.Height = branchParam.AsDouble();
|
|
}
|
|
|
|
|
|
|
|
CreateDuctT(mainDuct, mainDivide, HeadDuct);
|
|
CreateDuctT(branchDuct, branchDivide, HeadDuct);
|
|
|
|
return m_divideElemId;
|
|
}
|
|
|
|
//파이프T 커넥터3개로 작도하기
|
|
public void CreateDuctT(Duct Main1, Duct Main2, Duct Head)
|
|
{
|
|
|
|
//나뉘어진 메인관2개 가지관 1개 커넥트 구해 T작도
|
|
ConnectorManager duct_connectorManager2 = Main1.ConnectorManager;
|
|
ConnectorSet duct_connectorSet2 = duct_connectorManager2.Connectors;
|
|
ConnectorManager duct_connectorManager3 = Main2.ConnectorManager;
|
|
ConnectorSet duct_connectorSet3 = duct_connectorManager3.Connectors;
|
|
|
|
Connector duct_main1con = null;
|
|
Connector duct_main2con = null;
|
|
Connector duct_branchcon = null;
|
|
double minDist = double.MaxValue;
|
|
|
|
foreach (Connector maincon1 in duct_connectorSet2)
|
|
{
|
|
foreach (Connector maincon2 in duct_connectorSet3)
|
|
{
|
|
double d = maincon1.Origin.DistanceTo(maincon2.Origin);
|
|
if (d < minDist)
|
|
{
|
|
duct_main1con = maincon1;
|
|
duct_main2con = maincon2;
|
|
minDist = d;
|
|
}
|
|
}
|
|
}
|
|
|
|
ConnectorManager New_connectorManager = Head.ConnectorManager;
|
|
ConnectorSet New_connectorSet = New_connectorManager.Connectors;
|
|
Connector New_con = null;
|
|
double minDist2 = double.MaxValue;
|
|
|
|
foreach (Connector maincon1 in duct_connectorSet2)
|
|
{
|
|
foreach (Connector maincon3 in New_connectorSet)
|
|
{
|
|
double d = maincon1.Origin.DistanceTo(maincon3.Origin);
|
|
if (d < minDist2)
|
|
{
|
|
|
|
duct_main1con = maincon1;
|
|
New_con = maincon3;
|
|
minDist2 = d;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
FamilyInstance family = creDoc.NewTeeFitting(duct_main1con, duct_main2con, New_con);
|
|
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//덕트 커넥터점 2개 구하기
|
|
public List<XYZ> GetDuctConnectorPts(Duct duct)
|
|
{
|
|
List<XYZ> ptLst = new List<XYZ>();
|
|
|
|
ConnectorManager duct_connectorManager1 = duct.ConnectorManager;
|
|
ConnectorSet duct_connectorSet1 = duct_connectorManager1.Connectors;
|
|
|
|
foreach (Connector connector1 in duct_connectorSet1)
|
|
{
|
|
ptLst.Add(connector1.Origin);
|
|
}
|
|
|
|
return ptLst;
|
|
}
|
|
|
|
public class DuctSelectionFilter : ISelectionFilter
|
|
{
|
|
public bool AllowElement(Element element)
|
|
{
|
|
if (element.Category == null) return false;
|
|
if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctCurves)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public bool AllowReference(Reference refer, XYZ point)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool Pyosi(UIApplication uiapp, Document doc, XYZ pt)
|
|
{
|
|
using (Transaction transaction = new Transaction(doc))
|
|
{
|
|
transaction.Start("Start");
|
|
|
|
XYZ pt1 = new XYZ(pt.X - 0.328084, pt.Y + 0.328084, pt.Z);
|
|
XYZ pt2 = new XYZ(pt.X + Unit.MMToFeet(100), pt.Y + Unit.MMToFeet(100), pt.Z);
|
|
XYZ pt3 = new XYZ(pt.X + 0.328084, pt.Y - 0.328084, pt.Z);
|
|
XYZ pt4 = new XYZ(pt.X - 0.328084, pt.Y - 0.328084, pt.Z);
|
|
|
|
Autodesk.Revit.DB.View view = doc.ActiveView;
|
|
//Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), pt2, pt4);
|
|
//Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), pt1, pt3);
|
|
Util.CreateModelLine(doc, pt2, pt4);
|
|
Util.CreateModelLine(doc, pt1, pt3);
|
|
transaction.Commit();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public XYZ GetIntersectionPoint(XYZ p1, XYZ p2, XYZ p3, XYZ p4)
|
|
{
|
|
XYZ resPt = XYZ.Zero;
|
|
|
|
//p1 = Util.Polar(p1, p2, p1, 1);
|
|
//p2 = Util.Polar(p2, p1, p2, 1);
|
|
//p3 = Util.Polar(p3, p4, p3, 1);
|
|
//p4 = Util.Polar(p4, p3, p4, 1);
|
|
|
|
|
|
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;
|
|
|
|
resPt = new XYZ(x, y, 0);
|
|
|
|
return resPt;
|
|
}
|
|
|
|
static Definition GetDefinition(Element elem, string parameter_name)
|
|
{
|
|
IList<Parameter> ps = elem.GetParameters(parameter_name);
|
|
|
|
int n = ps.Count;
|
|
|
|
Debug.Assert(1 >= n, "expected maximum one shared parameters" + "named " + parameter_name);
|
|
|
|
Definition d = (0 == n)
|
|
? null
|
|
: ps[0].Definition;
|
|
|
|
return d;
|
|
}
|
|
}
|
|
}
|