173 lines
7.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
} |