Client/Desktop/KMBIM3.0/23.11.03/Cmd/Duct/FlexDuct/FdCmd.cs

315 lines
11 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using KDCS.Utils;
using KMBIM.Revit.Tools.Cmd.DuctFlexDuct;
using KMBIM.Revit.Tools.Utils;
using KMBIM.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace KMBIM.Revit.Tools.CmdDuct
{
public class PipeSelectionFilter : 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;
}
}
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 class DuctTerminalSelectionFilter : ISelectionFilter
{
public bool AllowElement(Element element)
{
if (element.Category == null) return false;
if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctTerminal)
{
return true;
}
return false;
}
public bool AllowReference(Reference refer, XYZ point)
{
return false;
}
}
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
public class FlexibleDuctDiffuserCmd : IExternalCommand
{
UIApplication m_pUIApp;
UIDocument uidoc = null;
Document doc = null;
List<ElementId> _added_emement_ids = new List<ElementId>();
Duct m_duct;
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
m_pUIApp = commandData.Application;
uidoc = m_pUIApp.ActiveUIDocument;
doc = uidoc.Document;
MechanicalSystemType ductSystemType = null;
Selection selection = uidoc.Selection;
try
{
// Looking for the DuctType
var lstFlexDuctType = new FilteredElementCollector(doc)
.OfClass(typeof(FlexDuctType))
.OfType<FlexDuctType>()
.ToList();
FlexDuctType flexDuctType = null;
foreach (FlexDuctType fdt in lstFlexDuctType)
{
if (fdt.Shape == ConnectorProfileType.Round)
{
flexDuctType = fdt;
break;
}
}
if (flexDuctType == null)
{
System.Windows.Forms.MessageBox.Show("사용가능한 원형 플렉시블덕트 유형이 없습니다.");
return Result.Failed;
}
FormFlexibleDuctSize frmFlexDuctSize = new FormFlexibleDuctSize(m_pUIApp);
Process process = Process.GetCurrentProcess();
IntPtr h = process.MainWindowHandle;
var hWndRevit = new WindowWrapper(h);
frmFlexDuctSize.Show(hWndRevit);
uidoc.RefreshActiveView();
//--------------------------------------------------------------------------------------------------------------------------------------
Reference refDuct = null;
try
{
refDuct=selection.PickObject(ObjectType.Element, new DuctSelectionFilter(), "덕트 선택");
}
catch (Exception){
}
if (refDuct == null)
{
frmFlexDuctSize.Close();
return Result.Failed;
}
Duct duct = doc.GetElement(refDuct.ElementId) as Duct;
if (duct == null)
{
frmFlexDuctSize.Close();
return Result.Failed;
}
var paramLevel = duct.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
var levelId = paramLevel.AsElementId();
ElementId ductSysTypeId = duct.MEPSystem.GetTypeId();
// 덕트 선을 지나는 수직 면
var lineDuct = (duct.Location as LocationCurve).Curve as Line;
XYZ faceNormaDuct = lineDuct.Direction.CrossProduct(XYZ.BasisZ);
Plane planeDuct = Plane.CreateByNormalAndOrigin(faceNormaDuct, lineDuct.GetEndPoint(0));
IList<Reference> lstReference = null;
double flexduct_dia = Unit.MMToFeet(150d);
try
{
lstReference = selection.PickObjects(ObjectType.Element, new DuctTerminalSelectionFilter(), "디퓨져 선택");
}
catch (Exception) {
}
if (lstReference == null)
{
frmFlexDuctSize.Close();
return Result.Failed;
}
foreach (var refDiffuser in lstReference)
{
FamilyInstance fi = doc.GetElement(refDiffuser.ElementId) as FamilyInstance;
if (fi != null)
{
if (fi.MEPModel == null) continue;
Connector connDiffuser = fi.MEPModel.ConnectorManager.Connectors.Cast<Connector>().First();
XYZ ptOnDuctVerticalFace = Util.Project(planeDuct, connDiffuser.Origin);
XYZ ptOnDuct = lineDuct.Project(ptOnDuctVerticalFace).XYZPoint;
Plane planeDiffuser = Plane.CreateByNormalAndOrigin(faceNormaDuct, connDiffuser.Origin);
XYZ ptUpDiffuser = Util.Project(planeDiffuser, ptOnDuct);
XYZ startTangent = (ptUpDiffuser - ptOnDuct).Normalize();
XYZ endTangent = (ptUpDiffuser - connDiffuser.Origin).Normalize();
XYZ pt1 = ptUpDiffuser - startTangent * Unit.MMToFeet(200d);
XYZ pt2 = ptUpDiffuser - endTangent * Unit.MMToFeet(200d);
XYZ pt3 = connDiffuser.Origin + endTangent * Unit.MMToFeet(10d);
List<XYZ> pts = new List<XYZ>();
pts.Add(ptOnDuct);
pts.Add(pt1);
//pts.Add(ptUpDiffuser);
pts.Add(pt2);
pts.Add(connDiffuser.Origin);
using (Transaction trans = new Transaction(doc))
{
trans.Start("Create FlexDuct");
FlexDuct flexDuct = FlexDuct.Create(doc, ductSysTypeId, flexDuctType.Id, levelId, startTangent, endTangent, pts);
flexduct_dia = frmFlexDuctSize.Diameter;
flexDuct.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).Set(flexduct_dia);
// FlexDuct flexDuct = doc.Create.NewFlexDuct(pts, flexDuctType);
double minDist = double.MaxValue;
double maxDist = double.MinValue;
double dst = 0d;
flexDuctType.PreferredJunctionType = JunctionType.Tap;
doc.Regenerate();
Connector conClosestFlexDuct = null;
foreach (Connector conDif in flexDuct.ConnectorManager.Connectors)
{
dst = conDif.Origin.DistanceTo(ptOnDuct);
if (dst < minDist)
{
conClosestFlexDuct = conDif;
minDist = dst;
}
}
if (conClosestFlexDuct != null)
{
doc.Create.NewTakeoffFitting(conClosestFlexDuct, duct as MEPCurve);
}
conClosestFlexDuct = null;
minDist = double.MaxValue;
foreach (Connector conDif in flexDuct.ConnectorManager.Connectors)
{
dst = conDif.Origin.DistanceTo(connDiffuser.Origin);
if (dst < minDist)
{
conClosestFlexDuct = conDif;
minDist = dst;
}
}
if (conClosestFlexDuct != null)
{
LocationCurve locCrv = flexDuct.Location as LocationCurve;
conClosestFlexDuct.ConnectTo(connDiffuser);
if (locCrv.Curve.GetEndPoint(0).DistanceTo(connDiffuser.Origin) < locCrv.Curve.GetEndPoint(1).DistanceTo(connDiffuser.Origin)) flexDuct.StartTangent = connDiffuser.CoordinateSystem.BasisZ;
else flexDuct.EndTangent = connDiffuser.CoordinateSystem.BasisZ;
}
trans.Commit();
}//end-using
}//end-foreach
}//end-if
frmFlexDuctSize.Close();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
return Result.Succeeded;
}
}
}