Client/Desktop/KMBIM3.0/23.10.18/Cmd/Stretch/Stretch.cs

212 lines
8.2 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;
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<Reference> pickRefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(ObjectType.Element, new SelectPipeDuct(), "신축할 설비요소 선택 :");
List<Element> ElemLst = new List<Element>();
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<Connector> m_CloseConLst = new List<Connector>();
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<Connector> 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;
}
}
}