Files
RookieStation/RookieStation/Drawing/ExecuteCmd/CreateWires.cs
2022-01-11 16:45:48 +08:00

173 lines
7.4 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using RookieStation.Utils;
using RookieStation.ParcelAreaModule.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
namespace RookieStation.Drawing.ExecuteCmd
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
internal class CreateWires : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
Document doc = uidoc.Document;
bool isContinue = true;
try
{
while (isContinue)
{
//var refers = uidoc.Selection.PickObjects(ObjectType.Element, new SelectFilter<FamilyInstance>(), "请选择灯具");
//var instances = refers.Select(refer => doc.GetElement(refer) as FamilyInstance);
var instances = uidoc.Selection.PickElementsByRectangle(new LightSelectFilter<FamilyInstance>(), "请选择灯具").Cast<FamilyInstance>();
//var instances = refers.Select(refer => doc.GetElement(refer) as FamilyInstance).OrderBy(fi => RsRevitUtils.GetLocationPointByElement(fi).X).ThenBy(fi => RsRevitUtils.GetLocationPointByElement(fi).Y);
var instancesGroupByX = instances.GroupBy(fi => Math.Round(RsRevitUtils.GetLocationPointByElement(fi).X, 5));
var instancesGroupByY = instances.GroupBy(fi => Math.Round(RsRevitUtils.GetLocationPointByElement(fi).Y, 5));
IOrderedEnumerable<FamilyInstance> instancesOrdered = null;
if (instancesGroupByX.Count() <= instancesGroupByY.Count())
{
instancesOrdered = instances.OrderBy(fi => Math.Round(RsRevitUtils.GetLocationPointByElement(fi).X, 5)).ThenBy(fi => Math.Round(RsRevitUtils.GetLocationPointByElement(fi).Y, 5));
}
else
{
instancesOrdered = instances.OrderBy(fi => Math.Round(RsRevitUtils.GetLocationPointByElement(fi).Y, 5)).ThenBy(fi => Math.Round(RsRevitUtils.GetLocationPointByElement(fi).X, 5));
}
doc.InvokeGroup<Result>(tg =>
{
for (int i = 0; i < instancesOrdered.Count() - 1; i++)
{
var fi = instancesOrdered.ElementAt(i);
var fi1 = instancesOrdered.ElementAt(i + 1);
try
{
CreateWire(doc, fi, fi1, i);
}
catch (Exception)
{
TaskDialog.Show("错误", "存在部分照明设备族未设置导线连接件");
return Result.Failed;
}
}
foreach (var instance in instances)
{
FamilyInstance closestInstance = null;
if (instance.MEPModel.ConnectorManager.UnusedConnectors.Size > 0)
{
var p = RsRevitUtils.GetLocationPointByElement(instance);
var mindistance = 10.0;
foreach (var instanceSearched in instances)
{
var sp = RsRevitUtils.GetLocationPointByElement(instanceSearched);
var sdistance = sp.DistanceTo(p);
if (sdistance < mindistance && sdistance != 0)
{
closestInstance = instanceSearched;
mindistance = sdistance;
}
}
try
{
CreateWire(doc, instance, closestInstance, 0);
}
catch (Exception)
{
TaskDialog.Show("错误", "存在部分照明设备族未设置导线连接件");
return Result.Failed;
}
}
}
return Result.Succeeded;
}, "创建导线");
}
return Result.Failed;
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return Result.Succeeded;
}
}
public void CreateWire(Document doc, FamilyInstance firstInstance, FamilyInstance endInstance, int i)
{
var wireTypeId = doc.GetDefaultElementTypeId(ElementTypeGroup.WireType);
var connManager = firstInstance.MEPModel.ConnectorManager;
//if (connManager == null)
//{
// TaskDialog.Show("错误", "存在部分照明设备族未设置导线连接件");
// return;
//}
var firstConnectors = connManager.Connectors;
Connector connector = null;
foreach (Connector it in firstConnectors)
{
connector = it;
break;
}
var loc = connector.Origin;
var endConnectors = endInstance.MEPModel.ConnectorManager.Connectors;
Connector connector1 = null;
foreach (Connector it in endConnectors)
{
connector1 = it;
break;
}
var loc1 = connector1.Origin;
List<XYZ> pts = new List<XYZ>
{
loc
};
var l = Line.CreateBound(loc, loc1);
//if (l.Length > 2200 / 304.8)
//{
// return;
//}
//if (l.Length > 3000 / 304.8)
//{
// return;
//}
var off = l.Direction.CrossProduct(XYZ.BasisZ * 2);
var cp = (loc + loc1) / 2;
if (i % 2 == 0)
{
pts.Add(off.Add(cp));
}
else
{
pts.Add(off.Negate().Add(cp));
}
pts.Add(loc1);
doc.Invoke(ts =>
{
Wire.Create(doc, wireTypeId, doc.ActiveView.Id, WiringType.Arc, pts, connector, connector1);
}, "创建导线");
}
internal class LightSelectFilter<T> : ISelectionFilter
{
public bool AllowElement(Autodesk.Revit.DB.Element elem)
{
return elem is T && elem.Category.Id.IntegerValue == -2001120;
}
public bool AllowReference(Reference refer, XYZ point)
{
return true;
}
}
}
}