315 lines
11 KiB
C#
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;
|
|
}
|
|
|
|
|
|
}
|
|
}
|