多项功能优化
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -44,10 +44,15 @@ namespace Sai.RvKits.RvMEP
|
||||
e is not InsulationLiningBase &&
|
||||
e is not FlexDuct &&
|
||||
e is not FlexPipe &&
|
||||
!(e.GetLocCurve() as Line).Direction.IsParallelTo(XYZ.BasisZ)),
|
||||
!(e.GetCurve() as Line).Direction.IsParallelTo(XYZ.BasisZ)),
|
||||
"请选择要整理的管线")
|
||||
.Select(e => e.Id)
|
||||
.ToList();
|
||||
if (ids.Count <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var baseId = uidoc.Selection
|
||||
.PickObject(
|
||||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||||
@@ -55,13 +60,8 @@ namespace Sai.RvKits.RvMEP
|
||||
"请选择基准管线")
|
||||
.ElementId;
|
||||
|
||||
if (ids.Count <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var baseElement = doc.GetElement(baseId);
|
||||
var baseLine = baseElement.GetLocCurve() as Line;
|
||||
var baseLine = baseElement.GetCurve() as Line;
|
||||
baseLine.MakeUnbound();
|
||||
if (IsHorizon)
|
||||
{
|
||||
@@ -72,10 +72,10 @@ namespace Sai.RvKits.RvMEP
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var elem = doc.GetElement(id);
|
||||
var l = elem.GetLocCurve() as Line;
|
||||
var l = elem.GetCurve() as Line;
|
||||
if (!l.Direction.IsParallelTo(baseLine.Direction))
|
||||
{
|
||||
MessageBox.Show("错误", "所选管线不平行");
|
||||
MessageBox.Show("所选管线不平行", "错误");
|
||||
return;
|
||||
}
|
||||
var d = baseLine.Distance(l.Origin);
|
||||
@@ -225,14 +225,14 @@ namespace Sai.RvKits.RvMEP
|
||||
{
|
||||
//通过LocationCurve确定相对位置关系
|
||||
var orderIds = ids.Select(id => doc.GetElement(id) as MEPCurve)
|
||||
.OrderBy(c => (c.GetLocCurve() as Line).Origin.Z).Select(e => e.Id).ToList();
|
||||
.OrderBy(c => (c.GetCurve() as Line).Origin.Z).Select(e => e.Id).ToList();
|
||||
//中心距
|
||||
if (MEPCurveCenter)
|
||||
{
|
||||
var baseIndex = orderIds.IndexOf(baseId);
|
||||
for (var i = 0; i < orderIds.Count; i++)
|
||||
{
|
||||
var currentZ = (doc.GetElement(orderIds[i]).GetLocCurve() as Line).Origin.Z;
|
||||
var currentZ = (doc.GetElement(orderIds[i]).GetCurve() as Line).Origin.Z;
|
||||
var dis = Math.Abs(baseLine.Origin.Z - currentZ);
|
||||
var actualDis = Math.Abs((baseIndex - i)) * Gap / 304.8;
|
||||
//判断方向
|
||||
@@ -255,7 +255,7 @@ namespace Sai.RvKits.RvMEP
|
||||
{
|
||||
ids.Remove(baseId);
|
||||
var groups = ids.Select(id => doc.GetElement(id) as MEPCurve)
|
||||
.OrderBy(c => (c.GetLocCurve() as Line).Origin.Z).GroupBy(e => (e.GetLocCurve() as Line).Origin.Z > baseLine.Origin.Z);
|
||||
.OrderBy(c => (c.GetCurve() as Line).Origin.Z).GroupBy(e => (e.GetCurve() as Line).Origin.Z > baseLine.Origin.Z);
|
||||
var baseTop = baseElement.get_BoundingBox(null).Max.Z;
|
||||
var baseBottom = baseElement.get_BoundingBox(null).Min.Z;
|
||||
if (baseElement is Pipe or Duct)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Electrical;
|
||||
@@ -9,6 +10,8 @@ using Autodesk.Revit.UI.Selection;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
|
||||
|
||||
using Sai.Toolkit.Revit.Helpers;
|
||||
|
||||
namespace Sai.RvKits.RvMEP;
|
||||
@@ -24,7 +27,11 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
var elemIds = UiDocument.Selection.GetElementIds();
|
||||
if (elemIds.Count == 0)
|
||||
{
|
||||
var reference = UiDocument.Selection.PickObject(ObjectType.Element, new FuncFilter(e => e is FamilyInstance ins && ins.MEPModel.ConnectorManager != null), "请选择族实例");
|
||||
var reference = UiDocument.Selection
|
||||
.PickObject(
|
||||
ObjectType.Element,
|
||||
new FuncFilter(e => e is FamilyInstance ins && ins.GetConnectors(true).Size > 0),
|
||||
"请选择族实例");
|
||||
elemIds.Add(Document.GetElement(reference).Id);
|
||||
}
|
||||
|
||||
@@ -34,15 +41,13 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
var cableTrayTypeId = Document.OfClass<CableTrayType>().FirstElementId();
|
||||
var conduitTypeId = Document.OfClass<ConduitType>().FirstElementId();
|
||||
|
||||
var filteredElementCollector = Document.OfClass<DuctType>();
|
||||
var ductTypeCollector = Document.OfClass<DuctType>().Cast<DuctType>();
|
||||
var roundDuctTypeId = ElementId.InvalidElementId;
|
||||
var rectangleDuctTypeId = ElementId.InvalidElementId;
|
||||
var ovalDuctTypeId = ElementId.InvalidElementId;
|
||||
|
||||
foreach (var element2 in filteredElementCollector)
|
||||
//设置默认的风管类型
|
||||
foreach (var ductType in ductTypeCollector)
|
||||
{
|
||||
var ductType = (DuctType)element2;
|
||||
|
||||
if (ductType.FamilyName == "圆形风管" || ductType.FamilyName.Contains("Round Duct"))
|
||||
{
|
||||
roundDuctTypeId = ductType.Id;
|
||||
@@ -65,7 +70,7 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
}
|
||||
CableTray referCabTray = null;
|
||||
Conduit referConduit = null;
|
||||
//拿到连接的管线的类型
|
||||
//根据连接件拿到连接的管线的类型
|
||||
foreach (Connector conn in elem.GetConnectors())
|
||||
{
|
||||
if (conn.IsConnected)
|
||||
@@ -117,8 +122,8 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
Document.Invoke(
|
||||
_ =>
|
||||
{
|
||||
var conns = elem.GetConnectors(true);
|
||||
foreach (Connector connector in conns)
|
||||
var connectors = elem.GetConnectors(true);
|
||||
foreach (Connector connector in connectors)
|
||||
{
|
||||
Element element = null;
|
||||
if (elem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_FabricationPipework)
|
||||
@@ -166,6 +171,7 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
}
|
||||
var extensionLength = connector.GetExtensionLength();
|
||||
var origin = connector.Origin;
|
||||
//延伸后的点
|
||||
var xyz2 = origin + (extensionLength * connector.CoordinateSystem.BasisZ);
|
||||
var levelId = elem.LevelId;
|
||||
if (levelId == ElementId.InvalidElementId)
|
||||
@@ -193,43 +199,43 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
break;
|
||||
//风管
|
||||
case Domain.DomainHvac:
|
||||
var mechanicalSystemTypes = new FilteredElementCollector(Document)
|
||||
.OfClass(typeof(MechanicalSystemType))
|
||||
.Cast<MechanicalSystemType>();
|
||||
//风管系统类型
|
||||
var mechanicalSystem =
|
||||
connector.MEPSystem == null
|
||||
? connector.DuctSystemType switch
|
||||
{
|
||||
//送风
|
||||
DuctSystemType.SupplyAir
|
||||
=> mechanicalSystemTypes.FirstOrDefault(
|
||||
pst =>
|
||||
pst.SystemClassification
|
||||
== Autodesk.Revit.DB.MEPSystemClassification.SupplyAir
|
||||
),
|
||||
//回风
|
||||
DuctSystemType.ReturnAir
|
||||
=> mechanicalSystemTypes.FirstOrDefault(
|
||||
pst =>
|
||||
pst.SystemClassification
|
||||
== Autodesk.Revit.DB.MEPSystemClassification.ReturnAir
|
||||
),
|
||||
//排风
|
||||
DuctSystemType.ExhaustAir
|
||||
=> mechanicalSystemTypes.FirstOrDefault(
|
||||
pst =>
|
||||
pst.SystemClassification
|
||||
== Autodesk.Revit.DB.MEPSystemClassification.ExhaustAir
|
||||
),
|
||||
_
|
||||
=> mechanicalSystemTypes.FirstOrDefault(
|
||||
pst =>
|
||||
pst.SystemClassification
|
||||
== Autodesk.Revit.DB.MEPSystemClassification.OtherAir
|
||||
)
|
||||
}
|
||||
: Document.GetElement(connector.MEPSystem.GetTypeId()) as MechanicalSystemType;
|
||||
//var mechanicalSystemTypes = new FilteredElementCollector(Document)
|
||||
// .OfClass(typeof(MechanicalSystemType))
|
||||
// .Cast<MechanicalSystemType>();
|
||||
////风管系统类型
|
||||
//var mechanicalSystem =
|
||||
// connector.MEPSystem == null
|
||||
// ? connector.DuctSystemType switch
|
||||
// {
|
||||
// //送风
|
||||
// DuctSystemType.SupplyAir
|
||||
// => mechanicalSystemTypes.FirstOrDefault(
|
||||
// pst =>
|
||||
// pst.SystemClassification
|
||||
// == Autodesk.Revit.DB.MEPSystemClassification.SupplyAir
|
||||
// ),
|
||||
// //回风
|
||||
// DuctSystemType.ReturnAir
|
||||
// => mechanicalSystemTypes.FirstOrDefault(
|
||||
// pst =>
|
||||
// pst.SystemClassification
|
||||
// == Autodesk.Revit.DB.MEPSystemClassification.ReturnAir
|
||||
// ),
|
||||
// //排风
|
||||
// DuctSystemType.ExhaustAir
|
||||
// => mechanicalSystemTypes.FirstOrDefault(
|
||||
// pst =>
|
||||
// pst.SystemClassification
|
||||
// == Autodesk.Revit.DB.MEPSystemClassification.ExhaustAir
|
||||
// ),
|
||||
// _
|
||||
// => mechanicalSystemTypes.FirstOrDefault(
|
||||
// pst =>
|
||||
// pst.SystemClassification
|
||||
// == Autodesk.Revit.DB.MEPSystemClassification.OtherAir
|
||||
// )
|
||||
// }
|
||||
// : Document.GetElement(connector.MEPSystem.GetTypeId()) as MechanicalSystemType;
|
||||
|
||||
//if (new FilteredElementCollector(Document).OfClass(typeof(DuctType)).FirstElement() is not DuctType)
|
||||
//{
|
||||
@@ -242,10 +248,9 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
case ConnectorProfileType.Round:
|
||||
element = Duct.Create(
|
||||
Document,
|
||||
mechanicalSystem.Id,
|
||||
roundDuctTypeId,
|
||||
levelId,
|
||||
origin,
|
||||
connector,
|
||||
xyz2
|
||||
);
|
||||
|
||||
@@ -256,31 +261,33 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
case ConnectorProfileType.Rectangular:
|
||||
element = Duct.Create(
|
||||
Document,
|
||||
mechanicalSystem.Id,
|
||||
rectangleDuctTypeId,
|
||||
levelId,
|
||||
origin,
|
||||
connector,
|
||||
xyz2
|
||||
);
|
||||
Document.Regenerate();
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(connector.Width);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(connector.Height);
|
||||
var width = Math.Max(connector.Width, connector.Height);
|
||||
var height = Math.Min(connector.Width, connector.Height);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(width);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(height);
|
||||
break;
|
||||
|
||||
case ConnectorProfileType.Oval:
|
||||
element = Duct.Create(Document, mechanicalSystem.Id, ovalDuctTypeId, levelId, origin, xyz2);
|
||||
element = Duct.Create(Document, ovalDuctTypeId, levelId, connector, xyz2);
|
||||
Document.Regenerate();
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(connector.Width);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(connector.Height);
|
||||
var w = Math.Max(connector.Width, connector.Height);
|
||||
var h = Math.Min(connector.Width, connector.Height);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(w);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(h);
|
||||
break;
|
||||
|
||||
default:
|
||||
element = Duct.Create(
|
||||
Document,
|
||||
mechanicalSystem.Id,
|
||||
roundDuctTypeId,
|
||||
levelId,
|
||||
origin,
|
||||
connector,
|
||||
xyz2
|
||||
);
|
||||
break;
|
||||
@@ -297,7 +304,7 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
.Cast<PipingSystemType>();
|
||||
if (pipeTypeId == ElementId.InvalidElementId)
|
||||
{
|
||||
pipeTypeId = Document.OfClass<PipeType>().WhereElementIsElementType().FirstElementId();
|
||||
pipeTypeId = Document.OfClass<PipeType>().FirstElementId();
|
||||
}
|
||||
var system = connector.MEPSystem;
|
||||
var pipingSystemType =
|
||||
@@ -435,9 +442,11 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
break;
|
||||
|
||||
case ConnectorProfileType.Rectangular:
|
||||
var width = Math.Max(connector.Width, connector.Height);
|
||||
var height = Math.Min(connector.Width, connector.Height);
|
||||
element = CableTray.Create(Document, cableTrayTypeId, origin, xyz2, levelId);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM).Set(connector.Width);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM).Set(connector.Height);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM).Set(width);
|
||||
element.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM).Set(height);
|
||||
if (referCabTray != null)
|
||||
{
|
||||
var value = referCabTray.get_Parameter(
|
||||
@@ -460,15 +469,81 @@ internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根
|
||||
continue;
|
||||
}
|
||||
var curve = element as MEPCurve;
|
||||
var manager = curve.ConnectorManager;
|
||||
var lter = manager.UnusedConnectors.ForwardIterator();
|
||||
while (lter.MoveNext())
|
||||
var conns = curve.ConnectorManager.UnusedConnectors.Cast<Connector>();
|
||||
foreach (var connect in conns)
|
||||
{
|
||||
var connect = lter.Current as Connector;
|
||||
if (connect.Origin.IsAlmostEqualTo(connector.Origin))
|
||||
{
|
||||
Debug.WriteLine("新建管线:");
|
||||
Debug.WriteLine(connect.CoordinateSystem.BasisX);
|
||||
Debug.WriteLine(connect.CoordinateSystem.BasisY);
|
||||
Debug.WriteLine(connect.CoordinateSystem.BasisZ);
|
||||
Debug.WriteLine("管件:");
|
||||
Debug.WriteLine(connector.CoordinateSystem.BasisX);
|
||||
Debug.WriteLine(connector.CoordinateSystem.BasisY);
|
||||
Debug.WriteLine(connector.CoordinateSystem.BasisZ);
|
||||
var isStandMEPCurve = connect.CoordinateSystem.BasisZ.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero);
|
||||
|
||||
if (isStandMEPCurve)
|
||||
{
|
||||
var angleX = Math.Acos(connect.CoordinateSystem.BasisX.DotProduct(connector.CoordinateSystem.BasisX));
|
||||
Debug.WriteLine(angleX);
|
||||
var crossProduct = connect.CoordinateSystem.BasisX
|
||||
.CrossProduct(connector.CoordinateSystem.BasisX).Normalize();
|
||||
var angle = Math.Acos(connect.CoordinateSystem.BasisX.DotProduct(connector.CoordinateSystem.BasisX));
|
||||
if (crossProduct.IsAlmostEqualTo(XYZ.Zero))
|
||||
{
|
||||
if (connect.CoordinateSystem.BasisX
|
||||
.IsAlmostEqualTo(connector.CoordinateSystem.BasisX))
|
||||
{
|
||||
ElementTransformUtils.RotateElement(
|
||||
Document,
|
||||
element.Id,
|
||||
Line.CreateUnbound(origin, XYZ.BasisZ),
|
||||
Math.PI / 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (angleX > Math.PI / 2)
|
||||
{
|
||||
ElementTransformUtils.RotateElement(
|
||||
Document,
|
||||
element.Id,
|
||||
Line.CreateUnbound(origin, XYZ.BasisZ),
|
||||
angleX - Math.PI / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ElementTransformUtils.RotateElement(
|
||||
Document,
|
||||
element.Id,
|
||||
Line.CreateUnbound(origin, XYZ.BasisZ),
|
||||
Math.PI / 2 - angleX);
|
||||
}
|
||||
}
|
||||
//if (Math.Abs(angleX - Math.PI / 2) > 0.001)
|
||||
//{
|
||||
// ElementTransformUtils.RotateElement(
|
||||
// Document,
|
||||
// element.Id,
|
||||
// Line.CreateUnbound(origin, crossProduct),
|
||||
// angleX - Math.PI / 2
|
||||
// );
|
||||
// Debug.WriteLine("旋转后新建管线:");
|
||||
// Debug.WriteLine(connect.CoordinateSystem.BasisX);
|
||||
// Debug.WriteLine(connect.CoordinateSystem.BasisY);
|
||||
// Debug.WriteLine(connect.CoordinateSystem.BasisZ);
|
||||
// Document.Regenerate();
|
||||
// angle = Math.Acos(connect.CoordinateSystem.BasisX.DotProduct(connector.CoordinateSystem.BasisX));
|
||||
// Debug.WriteLine(nameof(angle) + angle);
|
||||
//}
|
||||
}
|
||||
var conn = elem.GetConnectors(true).GetNearestConnector(connector.Origin);
|
||||
conn.ConnectTo(connect);
|
||||
if (!connect.IsConnectedTo(connector))
|
||||
{
|
||||
connect.ConnectTo(connector);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,14 +32,14 @@ public class BreakMEPCurveCmd : ExternalCommand
|
||||
var pointPicked = refer1.GlobalPoint;
|
||||
|
||||
var mepCurve = UiDocument.Document.GetElement(refer1) as MEPCurve;
|
||||
var loc = mepCurve.GetLocCurve() as Line;
|
||||
var loc = mepCurve.GetCurve() as Line;
|
||||
var d = loc.Direction;
|
||||
var halfGap = 20 / 304.8;
|
||||
var point1 = pointPicked - d * halfGap;
|
||||
var point2 = pointPicked + d * halfGap;
|
||||
|
||||
var breakPoint1 = mepCurve.GetLocCurve().Project(point1).XYZPoint;
|
||||
var breakPoint2 = mepCurve.GetLocCurve().Project(point2).XYZPoint;
|
||||
var breakPoint1 = mepCurve.GetCurve().Project(point1).XYZPoint;
|
||||
var breakPoint2 = mepCurve.GetCurve().Project(point2).XYZPoint;
|
||||
if (!loc.IsInsideEx(breakPoint1, halfGap) || !loc.IsInsideEx(breakPoint2, halfGap))
|
||||
{
|
||||
MessageBox.Show("打断点距离管线端点太近");
|
||||
|
||||
@@ -48,8 +48,8 @@ public class CableLayoutCmd : ExternalCommand
|
||||
var conduit = Conduit.Create(
|
||||
Document,
|
||||
conduitType.Id,
|
||||
mepCurve.GetLocCurve().GetEndPoint(0),
|
||||
mepCurve.GetLocCurve().GetEndPoint(1),
|
||||
mepCurve.GetCurve().GetEndPoint(0),
|
||||
mepCurve.GetCurve().GetEndPoint(1),
|
||||
mepCurve.LevelId
|
||||
);
|
||||
firstConduits.Add(conduit);
|
||||
@@ -71,7 +71,7 @@ public class CableLayoutCmd : ExternalCommand
|
||||
|
||||
foreach (var conduit in firstConduits)
|
||||
{
|
||||
var line = conduit.GetLocCurve() as Line;
|
||||
var line = conduit.GetCurve() as Line;
|
||||
var direction = line!.Direction.CrossProduct(XYZ.BasisZ);
|
||||
var id = ElementTransformUtils.CopyElement(Document, conduit.Id, direction * offest).FirstOrDefault();
|
||||
var conduitCopied = Document.GetElement(id) as Conduit;
|
||||
|
||||
@@ -10,8 +10,16 @@ namespace Sai.RvKits.RvMEP;
|
||||
[Regeneration(RegenerationOption.Manual)]
|
||||
public class ClashResolveCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
WinDialogHelper.ShowModeless<ClashResolveView>(new ClashResolveViewModel());
|
||||
}
|
||||
public override void Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
WinDialogHelper.ShowModeless<ClashResolveView>(new ClashResolveViewModel());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,8 +89,14 @@
|
||||
<ex:StackPanelEx Orientation="Horizontal" Spacing="5">
|
||||
<GroupBox ex:StackPanelEx.Fill="Fill" Header="参考方式">
|
||||
<UniformGrid Rows="1">
|
||||
<RadioButton Content="手动" IsChecked="{Binding LocationType, ConverterParameter={x:Static local:LocationType.Manual}, Converter={StaticResource ComparisonConverter}}" />
|
||||
<RadioButton Content="参考" IsChecked="{Binding LocationType, ConverterParameter={x:Static local:LocationType.Reference}, Converter={StaticResource ComparisonConverter}}" />
|
||||
<RadioButton
|
||||
Content="手动"
|
||||
IsChecked="{Binding LocationType, ConverterParameter={x:Static local:LocationType.Manual}, Converter={StaticResource ComparisonConverter}}"
|
||||
ToolTip="手动选取两点" />
|
||||
<RadioButton
|
||||
Content="参考"
|
||||
IsChecked="{Binding LocationType, ConverterParameter={x:Static local:LocationType.Reference}, Converter={StaticResource ComparisonConverter}}"
|
||||
ToolTip="选择相交的两条管线,将翻弯管线偏移一定距离" />
|
||||
</UniformGrid>
|
||||
</GroupBox>
|
||||
<GroupBox ex:StackPanelEx.Fill="Fill" Header="调整方式">
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI.Selection;
|
||||
using Autodesk.Windows;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
@@ -36,15 +38,15 @@ public partial class ClashResolveViewModel : ObservableObject
|
||||
private LocationType locationType = LocationType.Manual;
|
||||
|
||||
public ActionEventHandler ActionEventHandler { get; } = new();
|
||||
|
||||
partial void OnLocationTypeChanged(LocationType value)
|
||||
{
|
||||
KeyIntPtrHelper.RaiseEscTwice();
|
||||
}
|
||||
[RelayCommand]
|
||||
private void Closing()
|
||||
private static void Closing()
|
||||
{
|
||||
//关闭窗口退出选择
|
||||
if (!CanRunning)
|
||||
{
|
||||
KeyIntPtrHelper.ActionEsc();
|
||||
}
|
||||
KeyIntPtrHelper.RaiseEscTwice();
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanRunning))]
|
||||
@@ -74,7 +76,7 @@ public partial class ClashResolveViewModel : ObservableObject
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& mepCurve.GetCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
),
|
||||
"请选择翻弯的管线上的点"
|
||||
@@ -92,8 +94,8 @@ public partial class ClashResolveViewModel : ObservableObject
|
||||
"请选择另一个翻弯管线上的点或确定单侧翻弯的需要偏移一侧"
|
||||
);
|
||||
//两个断点,breakPoint1距离原直线起点近,反向时,交换值
|
||||
breakPoint1 = mepCurveToBend.GetLocCurve().Project(reference1.GlobalPoint).XYZPoint;
|
||||
breakPoint2 = mepCurveToBend.GetLocCurve().Project(reference2.GlobalPoint).XYZPoint;
|
||||
breakPoint1 = mepCurveToBend.GetCurve().Project(reference1.GlobalPoint).XYZPoint;
|
||||
breakPoint2 = mepCurveToBend.GetCurve().Project(reference2.GlobalPoint).XYZPoint;
|
||||
}
|
||||
break;
|
||||
case LocationType.Reference:
|
||||
@@ -104,21 +106,21 @@ public partial class ClashResolveViewModel : ObservableObject
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& mepCurve.GetCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
),
|
||||
"请选择参照的管线"
|
||||
);
|
||||
//参考的管线定位
|
||||
var referenceMEPCurve = doc.GetElement(reference);
|
||||
var referenceLine = referenceMEPCurve.GetLocCurve() as Line;
|
||||
var referenceLine = referenceMEPCurve.GetCurve() as Line;
|
||||
|
||||
var reference1 = uidoc.Selection.PickObject(
|
||||
ObjectType.PointOnElement,
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e is MEPCurve mepCurve and not InsulationLiningBase
|
||||
&& mepCurve.GetLocCurve() is Line line
|
||||
&& mepCurve.GetCurve() is Line line
|
||||
&& !line.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero)
|
||||
&& e.Id != referenceMEPCurve!.Id
|
||||
),
|
||||
@@ -126,7 +128,7 @@ public partial class ClashResolveViewModel : ObservableObject
|
||||
);
|
||||
//翻弯的管线定位
|
||||
mepCurveToBend = doc.GetElement(reference1) as MEPCurve;
|
||||
var bendLine = mepCurveToBend.GetLocCurve() as Line;
|
||||
var bendLine = mepCurveToBend.GetCurve() as Line;
|
||||
|
||||
var result = bendLine!.Intersect(referenceLine, out var array);
|
||||
|
||||
@@ -172,296 +174,302 @@ public partial class ClashResolveViewModel : ObservableObject
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
var originBaseLine = mepCurveToBend.GetCurve() as Line;
|
||||
var baseLine = originBaseLine!.Clone() as Line;
|
||||
//原管线的方向
|
||||
var direction = baseLine?.Direction;
|
||||
var startPoint = baseLine!.GetEndPoint(0);
|
||||
var endPoint = baseLine.GetEndPoint(1);
|
||||
var breakLine = Line.CreateBound(breakPoint1, breakPoint2);
|
||||
//var minLength = mepCurveToBend.GetConnectors().OfType<Connector>().FirstOrDefault().GetExtensionLength();
|
||||
//if (breakLine.Length < minLength)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
var translateDirection = AdjustDirection switch
|
||||
{
|
||||
AdjustDirection.Up => XYZ.BasisZ,
|
||||
AdjustDirection.Down => -XYZ.BasisZ,
|
||||
AdjustDirection.Left => XYZ.BasisZ.CrossProduct(breakLine.Direction),
|
||||
AdjustDirection.Right => -XYZ.BasisZ.CrossProduct(breakLine.Direction),
|
||||
_ => null
|
||||
};
|
||||
switch (AdjustType)
|
||||
{
|
||||
case AdjustType.OneSide:
|
||||
|
||||
{
|
||||
MEPCurve baseMepCurve1;
|
||||
MEPCurve baseMepCurve2;
|
||||
|
||||
var newMepCurveId = mepCurveToBend.BreakByPoint(breakPoint1);
|
||||
var newMepCurve = doc.GetElement(newMepCurveId) as MEPCurve;
|
||||
|
||||
//baseMepCurve2始终是打断后生成的新管线,并且是需要偏移的管线
|
||||
if ((newMepCurve.GetCurve() as Line).IsInsideEx(breakPoint2))
|
||||
{
|
||||
baseMepCurve1 = mepCurveToBend;
|
||||
baseMepCurve2 = newMepCurve;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseMepCurve1 = newMepCurve;
|
||||
baseMepCurve2 = mepCurveToBend;
|
||||
}
|
||||
//移动新生成的管线
|
||||
ElementTransformUtils.MoveElement(
|
||||
doc,
|
||||
baseMepCurve2.Id,
|
||||
translateDirection * Offset / 304.8
|
||||
);
|
||||
doc.Regenerate();
|
||||
////偏移变换
|
||||
//var translateTransform = Transform.CreateTranslation(translateDirection * Offset / 304.8);
|
||||
//
|
||||
//var originOffsetUnboundLine = baseLine.CreateTransformed(translateTransform) as Line;
|
||||
//需要偏移直线定位线
|
||||
var originOffsetUnboundLine = baseMepCurve2.GetCurve();
|
||||
//用于判断交点是否在偏移后的直线内,避免生成不了
|
||||
var originOffsetLine = originOffsetUnboundLine.Clone() as Line;
|
||||
originOffsetUnboundLine.MakeUnbound();
|
||||
|
||||
var radian = Angle.ToRadian();
|
||||
//反向时角度取补角
|
||||
if (breakLine.Direction.IsAlmostEqualTo(-direction))
|
||||
{
|
||||
radian = (180 - Angle).ToRadian();
|
||||
}
|
||||
|
||||
var rotation = Transform.CreateRotationAtPoint(
|
||||
direction.CrossProduct(translateDirection),
|
||||
radian,
|
||||
breakPoint1
|
||||
);
|
||||
//因为原来的管线可能被移动,所以用baseline的克隆线
|
||||
var unboundAngleLine = baseLine.CreateTransformed(rotation) as Line;
|
||||
unboundAngleLine!.MakeUnbound();
|
||||
//偏移管线与倾斜管线交点
|
||||
var offsetIntersectPoint = originOffsetUnboundLine.IntersectionPoint(unboundAngleLine);
|
||||
var isInside = originOffsetLine.IsInsideEx(offsetIntersectPoint); //当角度线于偏移直线交点在偏移直线内时
|
||||
//var flag2 = breakPoint1!.DistanceTo(offsetIntersectPoint) > minLength; //偏移间距大于一定一定值
|
||||
if (!isInside)
|
||||
{
|
||||
MessageBox.Show("管线偏移角度过大或过小,导致交点不在偏移的管线范围内");
|
||||
break;
|
||||
}
|
||||
//if (!flag2)
|
||||
//{
|
||||
// MessageBox.Show("管线偏移距离过近");
|
||||
// break;
|
||||
//}
|
||||
//if (isInside)
|
||||
else
|
||||
{
|
||||
var angleLine = Line.CreateBound(breakPoint1, offsetIntersectPoint);
|
||||
var angleMepCurve = mepCurveToBend.CopyAndSetLocationCurve(angleLine);
|
||||
|
||||
//拿到角度管的偏移交点处的连接件
|
||||
var angleMEPCurveIntersectPointConnector = angleMepCurve
|
||||
.GetConnectors(true)
|
||||
.GetNearestConnector(offsetIntersectPoint);
|
||||
//移动后的管线原有的连接件中,不用连接角度曲线的连接件,用来确定移动后管线的定位线
|
||||
Connector originOffsetConnector = null;
|
||||
|
||||
foreach (Connector conn in baseMepCurve2.GetConnectors(true))
|
||||
{
|
||||
//90度时,偏移管线的两个连接都是90度,但要选择偏移管原有的,非打断处的连接件
|
||||
if (
|
||||
conn.CoordinateSystem.BasisZ.DotProduct(
|
||||
angleMEPCurveIntersectPointConnector.CoordinateSystem.BasisZ
|
||||
) >= 0
|
||||
&& !offsetIntersectPoint.IsAlmostEqualTo(conn.Origin)
|
||||
) //锐角
|
||||
{
|
||||
originOffsetConnector = conn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
//if (originOffsetConnector != null && offsetIntersectPoint.DistanceTo(originOffsetConnector.Origin) > minLength)
|
||||
if (originOffsetConnector != null)
|
||||
{
|
||||
var finalOffsetLine = Line.CreateBound(
|
||||
offsetIntersectPoint,
|
||||
originOffsetConnector.Origin
|
||||
);
|
||||
baseMepCurve2.SetLocationCurve(finalOffsetLine);
|
||||
}
|
||||
|
||||
|
||||
var conn1 = ConnectorAssist.GetNearestConnectors(
|
||||
baseMepCurve1,
|
||||
angleMepCurve
|
||||
);
|
||||
doc.Create.NewElbowFitting(conn1[0], conn1[1]);
|
||||
|
||||
var conn2 = ConnectorAssist.GetNearestConnectors(
|
||||
angleMepCurve,
|
||||
baseMepCurve2
|
||||
);
|
||||
doc.Create.NewElbowFitting(conn2[0], conn2[1]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
ex.Message.ToLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AdjustType.TwoSide:
|
||||
|
||||
{
|
||||
MEPCurve baseMepCurve1;
|
||||
MEPCurve baseMepCurve2;
|
||||
//选择点的方向与原直线方向相反时,使得breakPoint1~breakPoint2始终与原直线同向
|
||||
if (breakLine.Direction.IsAlmostEqualTo(-baseLine.Direction))
|
||||
{
|
||||
//交换值
|
||||
(breakPoint1, breakPoint2) = (breakPoint2, breakPoint1);
|
||||
}
|
||||
|
||||
//doc.Regenerate();
|
||||
//偏移变换
|
||||
var translateTransform = Transform.CreateTranslation(
|
||||
translateDirection * Offset / 304.8
|
||||
);
|
||||
//偏移直线
|
||||
var offsetLine = baseLine.CreateTransformed(translateTransform) as Line;
|
||||
offsetLine!.MakeUnbound();
|
||||
//根据角度旋转的矩阵变换,创建变换后的直线
|
||||
//第一个交点
|
||||
var rotateTransform1 = Transform.CreateRotationAtPoint(
|
||||
direction.CrossProduct(translateDirection),
|
||||
Angle.ToRadian(),
|
||||
breakPoint1
|
||||
);
|
||||
var angleLine1 = baseLine.CreateTransformed(rotateTransform1) as Line;
|
||||
angleLine1!.MakeUnbound();
|
||||
var offsetPoint1 = offsetLine.IntersectionPoint(angleLine1);
|
||||
|
||||
//根据角度旋转的矩阵变换,创建变换后的直线
|
||||
//第二个交点
|
||||
var rotateTransform2 = Transform.CreateRotationAtPoint(
|
||||
direction.CrossProduct(translateDirection),
|
||||
(180 - Angle).ToRadian(),
|
||||
breakPoint2
|
||||
);
|
||||
var angleLine2 = baseLine.CreateTransformed(rotateTransform2) as Line;
|
||||
angleLine2!.MakeUnbound();
|
||||
var offsetPoint2 = offsetLine.IntersectionPoint(angleLine2);
|
||||
var b = Line.CreateBound(offsetPoint1, offsetPoint2);
|
||||
if (b.Direction.IsAlmostEqualTo(-baseLine.Direction))
|
||||
{
|
||||
Debug.WriteLine("翻弯的管线交叉");
|
||||
MessageBox.Show(
|
||||
"两点距离太近,无法翻弯",
|
||||
"提醒",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information
|
||||
);
|
||||
ts.RollBack();
|
||||
break;
|
||||
}
|
||||
|
||||
var newMepCurveId = mepCurveToBend.BreakByPoint(breakPoint1);
|
||||
var newMepCurve = doc.GetElement(newMepCurveId) as MEPCurve;
|
||||
//判断打断生成的新管线的位置是原管线的前端还是后端
|
||||
if ((newMepCurve.GetCurve() as Line).IsInsideEx(breakPoint2)) //后端
|
||||
{
|
||||
baseMepCurve1 = mepCurveToBend;
|
||||
baseMepCurve2 = newMepCurve;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseMepCurve1 = newMepCurve;
|
||||
baseMepCurve2 = mepCurveToBend;
|
||||
}
|
||||
|
||||
//第一条管线
|
||||
var newBaseLine1 = Line.CreateBound(startPoint, breakPoint1);
|
||||
//第二条管线
|
||||
var newBaseLine2 = Line.CreateBound(breakPoint2, endPoint);
|
||||
baseMepCurve1.SetLocationCurve(newBaseLine1);
|
||||
baseMepCurve2.SetLocationCurve(newBaseLine2);
|
||||
//生成的偏移线方向相反时,会导致两条翻弯的管线交叉
|
||||
|
||||
//第一根翻弯管
|
||||
var firstMepCurve = mepCurveToBend.CopyAndSetLocationCurve(
|
||||
Line.CreateBound(breakPoint1, offsetPoint1)
|
||||
);
|
||||
//偏移管
|
||||
var secondMepCurve = mepCurveToBend.CopyAndSetLocationCurve(
|
||||
Line.CreateBound(offsetPoint1, offsetPoint2)
|
||||
);
|
||||
//第二根翻弯管
|
||||
var thirdMepCurve = mepCurveToBend.CopyAndSetLocationCurve(
|
||||
Line.CreateBound(offsetPoint2, breakPoint2)
|
||||
);
|
||||
|
||||
doc.Regenerate();
|
||||
try
|
||||
{
|
||||
var connectors1 = ConnectorAssist.GetNearestConnectors(
|
||||
baseMepCurve1,
|
||||
firstMepCurve
|
||||
);
|
||||
doc.Create.NewElbowFitting(connectors1[0], connectors1[1]);
|
||||
var connectors4 = ConnectorAssist.GetNearestConnectors(
|
||||
thirdMepCurve,
|
||||
baseMepCurve2
|
||||
);
|
||||
doc.Create.NewElbowFitting(connectors4[0], connectors4[1]);
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
|
||||
{
|
||||
MessageBox.Show("角度过大或过小", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Message.ToLog();
|
||||
}
|
||||
try
|
||||
{
|
||||
var connectors2 = ConnectorAssist.GetNearestConnectors(
|
||||
firstMepCurve,
|
||||
secondMepCurve
|
||||
);
|
||||
doc.Create.NewElbowFitting(connectors2[0], connectors2[1]);
|
||||
var connectors3 = ConnectorAssist.GetNearestConnectors(
|
||||
secondMepCurve,
|
||||
thirdMepCurve
|
||||
);
|
||||
doc.Create.NewElbowFitting(connectors3[0], connectors3[1]);
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
|
||||
{
|
||||
MessageBox.Show("角度过大或过小", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Message.ToLog();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
CanRunning = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var originBaseLine = mepCurveToBend.GetLocCurve() as Line;
|
||||
var baseLine = originBaseLine!.Clone() as Line;
|
||||
//原管线的方向
|
||||
var direction = baseLine?.Direction;
|
||||
var startPoint = baseLine!.GetEndPoint(0);
|
||||
var endPoint = baseLine.GetEndPoint(1);
|
||||
var breakLine = Line.CreateBound(breakPoint1, breakPoint2);
|
||||
//var minLength = mepCurveToBend.GetConnectors().OfType<Connector>().FirstOrDefault().GetExtensionLength();
|
||||
//if (breakLine.Length < minLength)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
var translateDirection = AdjustDirection switch
|
||||
catch (Exception)
|
||||
{
|
||||
AdjustDirection.Up => XYZ.BasisZ,
|
||||
AdjustDirection.Down => -XYZ.BasisZ,
|
||||
AdjustDirection.Left => XYZ.BasisZ.CrossProduct(breakLine.Direction),
|
||||
AdjustDirection.Right => -XYZ.BasisZ.CrossProduct(breakLine.Direction),
|
||||
_ => null
|
||||
};
|
||||
switch (AdjustType)
|
||||
{
|
||||
case AdjustType.OneSide:
|
||||
|
||||
{
|
||||
MEPCurve baseMepCurve1;
|
||||
MEPCurve baseMepCurve2;
|
||||
|
||||
var newMepCurveId = mepCurveToBend.BreakByPoint(breakPoint1);
|
||||
var newMepCurve = doc.GetElement(newMepCurveId) as MEPCurve;
|
||||
|
||||
//baseMepCurve2始终是打断后生成的新管线,并且是需要偏移的管线
|
||||
if ((newMepCurve.GetLocCurve() as Line).IsInsideEx(breakPoint2))
|
||||
{
|
||||
baseMepCurve1 = mepCurveToBend;
|
||||
baseMepCurve2 = newMepCurve;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseMepCurve1 = newMepCurve;
|
||||
baseMepCurve2 = mepCurveToBend;
|
||||
}
|
||||
//移动新生成的管线
|
||||
ElementTransformUtils.MoveElement(
|
||||
doc,
|
||||
baseMepCurve2.Id,
|
||||
translateDirection * Offset / 304.8
|
||||
);
|
||||
doc.Regenerate();
|
||||
////偏移变换
|
||||
//var translateTransform = Transform.CreateTranslation(translateDirection * Offset / 304.8);
|
||||
//
|
||||
//var originOffsetUnboundLine = baseLine.CreateTransformed(translateTransform) as Line;
|
||||
//需要偏移直线定位线
|
||||
var originOffsetUnboundLine = baseMepCurve2.GetLocCurve();
|
||||
//用于判断交点是否在偏移后的直线内,避免生成不了
|
||||
var originOffsetLine = originOffsetUnboundLine.Clone() as Line;
|
||||
originOffsetUnboundLine.MakeUnbound();
|
||||
|
||||
var radian = Angle.ToRadian();
|
||||
//反向时角度取补角
|
||||
if (breakLine.Direction.IsAlmostEqualTo(-direction))
|
||||
{
|
||||
radian = (180 - Angle).ToRadian();
|
||||
}
|
||||
|
||||
var rotation = Transform.CreateRotationAtPoint(
|
||||
direction.CrossProduct(translateDirection),
|
||||
radian,
|
||||
breakPoint1
|
||||
);
|
||||
//因为原来的管线可能被移动,所以用baseline的克隆线
|
||||
var unboundAngleLine = baseLine.CreateTransformed(rotation) as Line;
|
||||
unboundAngleLine!.MakeUnbound();
|
||||
//偏移管线与倾斜管线交点
|
||||
var offsetIntersectPoint = originOffsetUnboundLine.IntersectionPoint(unboundAngleLine);
|
||||
var isInside = originOffsetLine.IsInsideEx(offsetIntersectPoint); //当角度线于偏移直线交点在偏移直线内时
|
||||
//var flag2 = breakPoint1!.DistanceTo(offsetIntersectPoint) > minLength; //偏移间距大于一定一定值
|
||||
if (!isInside)
|
||||
{
|
||||
MessageBox.Show("管线偏移角度过大或过小,导致交点不在偏移的管线范围内");
|
||||
break;
|
||||
}
|
||||
//if (!flag2)
|
||||
//{
|
||||
// MessageBox.Show("管线偏移距离过近");
|
||||
// break;
|
||||
//}
|
||||
//if (isInside)
|
||||
else
|
||||
{
|
||||
var angleLine = Line.CreateBound(breakPoint1, offsetIntersectPoint);
|
||||
var angleMepCurve = mepCurveToBend.CopyAndSetLocationCurve(angleLine);
|
||||
|
||||
//拿到角度管的偏移交点处的连接件
|
||||
var angleMEPCurveIntersectPointConnector = angleMepCurve
|
||||
.GetConnectors(true)
|
||||
.GetNearestConnector(offsetIntersectPoint);
|
||||
//移动后的管线原有的连接件中,不用连接角度曲线的连接件,用来确定移动后管线的定位线
|
||||
Connector originOffsetConnector = null;
|
||||
|
||||
foreach (Connector conn in baseMepCurve2.GetConnectors(true))
|
||||
{
|
||||
//90度时,偏移管线的两个连接都是90度,但要选择偏移管原有的,非打断处的连接件
|
||||
if (
|
||||
conn.CoordinateSystem.BasisZ.DotProduct(
|
||||
angleMEPCurveIntersectPointConnector.CoordinateSystem.BasisZ
|
||||
) >= 0
|
||||
&& !offsetIntersectPoint.IsAlmostEqualTo(conn.Origin)
|
||||
) //锐角
|
||||
{
|
||||
originOffsetConnector = conn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if (originOffsetConnector != null && offsetIntersectPoint.DistanceTo(originOffsetConnector.Origin) > minLength)
|
||||
if (originOffsetConnector != null)
|
||||
{
|
||||
var finalOffsetLine = Line.CreateBound(
|
||||
offsetIntersectPoint,
|
||||
originOffsetConnector.Origin
|
||||
);
|
||||
baseMepCurve2.SetLocationCurve(finalOffsetLine);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var conn1 = ConnectorAssist.GetNearestConnectors(
|
||||
baseMepCurve1,
|
||||
angleMepCurve
|
||||
);
|
||||
doc.Create.NewElbowFitting(conn1[0], conn1[1]);
|
||||
|
||||
var conn2 = ConnectorAssist.GetNearestConnectors(
|
||||
angleMepCurve,
|
||||
baseMepCurve2
|
||||
);
|
||||
doc.Create.NewElbowFitting(conn2[0], conn2[1]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
ex.Message.ToLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AdjustType.TwoSide:
|
||||
|
||||
{
|
||||
MEPCurve baseMepCurve1;
|
||||
MEPCurve baseMepCurve2;
|
||||
//选择点的方向与原直线方向相反时,使得breakPoint1~breakPoint2始终与原直线同向
|
||||
if (breakLine.Direction.IsAlmostEqualTo(-baseLine.Direction))
|
||||
{
|
||||
//交换值
|
||||
(breakPoint1, breakPoint2) = (breakPoint2, breakPoint1);
|
||||
}
|
||||
|
||||
//doc.Regenerate();
|
||||
//偏移变换
|
||||
var translateTransform = Transform.CreateTranslation(
|
||||
translateDirection * Offset / 304.8
|
||||
);
|
||||
//偏移直线
|
||||
var offsetLine = baseLine.CreateTransformed(translateTransform) as Line;
|
||||
offsetLine!.MakeUnbound();
|
||||
//根据角度旋转的矩阵变换,创建变换后的直线
|
||||
//第一个交点
|
||||
var rotateTransform1 = Transform.CreateRotationAtPoint(
|
||||
direction.CrossProduct(translateDirection),
|
||||
Angle.ToRadian(),
|
||||
breakPoint1
|
||||
);
|
||||
var angleLine1 = baseLine.CreateTransformed(rotateTransform1) as Line;
|
||||
angleLine1!.MakeUnbound();
|
||||
var offsetPoint1 = offsetLine.IntersectionPoint(angleLine1);
|
||||
|
||||
//根据角度旋转的矩阵变换,创建变换后的直线
|
||||
//第二个交点
|
||||
var rotateTransform2 = Transform.CreateRotationAtPoint(
|
||||
direction.CrossProduct(translateDirection),
|
||||
(180 - Angle).ToRadian(),
|
||||
breakPoint2
|
||||
);
|
||||
var angleLine2 = baseLine.CreateTransformed(rotateTransform2) as Line;
|
||||
angleLine2!.MakeUnbound();
|
||||
var offsetPoint2 = offsetLine.IntersectionPoint(angleLine2);
|
||||
var b = Line.CreateBound(offsetPoint1, offsetPoint2);
|
||||
if (b.Direction.IsAlmostEqualTo(-baseLine.Direction))
|
||||
{
|
||||
Debug.WriteLine("翻弯的管线交叉");
|
||||
MessageBox.Show(
|
||||
"两点距离太近,无法翻弯",
|
||||
"提醒",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information
|
||||
);
|
||||
ts.RollBack();
|
||||
break;
|
||||
}
|
||||
|
||||
var newMepCurveId = mepCurveToBend.BreakByPoint(breakPoint1);
|
||||
var newMepCurve = doc.GetElement(newMepCurveId) as MEPCurve;
|
||||
//判断打断生成的新管线的位置是原管线的前端还是后端
|
||||
if ((newMepCurve.GetLocCurve() as Line).IsInsideEx(breakPoint2)) //后端
|
||||
{
|
||||
baseMepCurve1 = mepCurveToBend;
|
||||
baseMepCurve2 = newMepCurve;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseMepCurve1 = newMepCurve;
|
||||
baseMepCurve2 = mepCurveToBend;
|
||||
}
|
||||
|
||||
//第一条管线
|
||||
var newBaseLine1 = Line.CreateBound(startPoint, breakPoint1);
|
||||
//第二条管线
|
||||
var newBaseLine2 = Line.CreateBound(breakPoint2, endPoint);
|
||||
baseMepCurve1.SetLocationCurve(newBaseLine1);
|
||||
baseMepCurve2.SetLocationCurve(newBaseLine2);
|
||||
//生成的偏移线方向相反时,会导致两条翻弯的管线交叉
|
||||
|
||||
//第一根翻弯管
|
||||
var firstMepCurve = mepCurveToBend.CopyAndSetLocationCurve(
|
||||
Line.CreateBound(breakPoint1, offsetPoint1)
|
||||
);
|
||||
//偏移管
|
||||
var secondMepCurve = mepCurveToBend.CopyAndSetLocationCurve(
|
||||
Line.CreateBound(offsetPoint1, offsetPoint2)
|
||||
);
|
||||
//第二根翻弯管
|
||||
var thirdMepCurve = mepCurveToBend.CopyAndSetLocationCurve(
|
||||
Line.CreateBound(offsetPoint2, breakPoint2)
|
||||
);
|
||||
|
||||
doc.Regenerate();
|
||||
try
|
||||
{
|
||||
var connectors1 = ConnectorAssist.GetNearestConnectors(
|
||||
baseMepCurve1,
|
||||
firstMepCurve
|
||||
);
|
||||
doc.Create.NewElbowFitting(connectors1[0], connectors1[1]);
|
||||
var connectors4 = ConnectorAssist.GetNearestConnectors(
|
||||
thirdMepCurve,
|
||||
baseMepCurve2
|
||||
);
|
||||
doc.Create.NewElbowFitting(connectors4[0], connectors4[1]);
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
|
||||
{
|
||||
MessageBox.Show("角度过大或过小", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Message.ToLog();
|
||||
}
|
||||
try
|
||||
{
|
||||
var connectors2 = ConnectorAssist.GetNearestConnectors(
|
||||
firstMepCurve,
|
||||
secondMepCurve
|
||||
);
|
||||
doc.Create.NewElbowFitting(connectors2[0], connectors2[1]);
|
||||
var connectors3 = ConnectorAssist.GetNearestConnectors(
|
||||
secondMepCurve,
|
||||
thirdMepCurve
|
||||
);
|
||||
doc.Create.NewElbowFitting(connectors3[0], connectors3[1]);
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
|
||||
{
|
||||
MessageBox.Show("角度过大或过小", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Message.ToLog();
|
||||
}
|
||||
}
|
||||
break;
|
||||
CanRunning = true;
|
||||
return;
|
||||
}
|
||||
},
|
||||
"碰撞处理"
|
||||
|
||||
@@ -119,7 +119,7 @@ public class CorrectMEPCurveSlopeCmd : ExternalCommand
|
||||
case Duct:
|
||||
{
|
||||
var param = mepCurve.get_Parameter(BuiltInParameter.RBS_DUCT_SLOPE);
|
||||
var loc = mepCurve.GetLocCurve() as Line;
|
||||
var loc = mepCurve.GetCurve() as Line;
|
||||
|
||||
isError = param.HasValue && ((param.AsDouble() < 0.025 && param.AsDouble() > 0) || param.AsDouble() > 0.055); //坡度过大或过小时
|
||||
break;
|
||||
|
||||
@@ -25,7 +25,7 @@ public class HeadroomCheckCmd : ExternalCommand
|
||||
Element element = null;
|
||||
foreach (var item in elems)
|
||||
{
|
||||
if (item.GetLocCurve().Length < minLength)
|
||||
if (item.GetCurve().Length < minLength)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ public partial class InsulationItem : ObservableValidator
|
||||
private double maxDiameter;
|
||||
|
||||
[Range(0, 1000)]
|
||||
|
||||
public double MinDiameter
|
||||
{
|
||||
get => minDiameter;
|
||||
@@ -44,12 +43,14 @@ public partial class InsulationItem : ObservableValidator
|
||||
|
||||
[Required]
|
||||
[Range(10, 1000)]
|
||||
public double Thickness
|
||||
{
|
||||
get => thickness;
|
||||
set => SetProperty(ref thickness, value, true);
|
||||
}
|
||||
[NotifyDataErrorInfo]
|
||||
[ObservableProperty]
|
||||
private double thickness;
|
||||
//{
|
||||
// get => thickness;
|
||||
// set => SetProperty(ref thickness, value, true);
|
||||
//}
|
||||
//private double thickness;
|
||||
|
||||
[ObservableProperty]
|
||||
private PipeInsulationType pipeInsulationType;
|
||||
|
||||
@@ -17,37 +17,19 @@ public class MoveConnectCmd : ExternalCommand
|
||||
Reference moveReference;
|
||||
try
|
||||
{
|
||||
FuncFilter filter =
|
||||
new(
|
||||
e =>
|
||||
((e is MEPCurve mep and not InsulationLiningBase) && mep.GetConnectors(true).Size > 0)
|
||||
|| (
|
||||
e is FamilyInstance instance
|
||||
&& instance.MEPModel.ConnectorManager != null
|
||||
&& instance.MEPModel.ConnectorManager.UnusedConnectors.Size > 0
|
||||
)
|
||||
);
|
||||
|
||||
baseReference = UiDocument.Selection.PickObject(
|
||||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||||
filter,
|
||||
new FuncFilter(e => e.GetConnectors(true)?.Size > 0),
|
||||
"请选择基准的管线、管件、设备实例"
|
||||
);
|
||||
FuncFilter filter1 =
|
||||
new(
|
||||
e =>
|
||||
e.Id != baseReference.ElementId
|
||||
&& ((e is MEPCurve mep and not InsulationLiningBase) && mep.GetConnectors(true).Size > 0)
|
||||
|| (
|
||||
e is FamilyInstance instance
|
||||
&& instance.MEPModel.ConnectorManager != null
|
||||
&& instance.MEPModel.ConnectorManager.UnusedConnectors.Size > 0
|
||||
&& instance.Id != baseReference.ElementId
|
||||
)
|
||||
);
|
||||
|
||||
moveReference = UiDocument.Selection.PickObject(
|
||||
Autodesk.Revit.UI.Selection.ObjectType.Element,
|
||||
filter,
|
||||
new FuncFilter(
|
||||
e =>
|
||||
e.Id != baseReference.ElementId
|
||||
&& e.GetConnectors(true)?.Size > 0
|
||||
),
|
||||
"请选择需要移动连接的管线、管件、设备实例"
|
||||
);
|
||||
}
|
||||
@@ -120,7 +102,7 @@ public class MoveConnectCmd : ExternalCommand
|
||||
else
|
||||
{
|
||||
//避免交点在原管线外,导致反向连接
|
||||
if ((mainMEPCurve.GetLocCurve() as Line).IsInsideEx(intersectPoint, 0.5))
|
||||
if ((mainMEPCurve.GetCurve() as Line).IsInsideEx(intersectPoint, 0.5))
|
||||
{
|
||||
ElementTransformUtils.MoveElement(Document, elementToMove!.Id, intersectPoint - origin2);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public partial class MoveMEPCurveViewModel : ObservableValidator
|
||||
|
||||
if (!CanRunning)
|
||||
{
|
||||
KeyIntPtrHelper.ActionEsc();
|
||||
KeyIntPtrHelper.RaiseEscTwice();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -114,7 +114,7 @@ public partial class StandMepCurveViewModel : ObservableObject
|
||||
return;
|
||||
}
|
||||
|
||||
KeyIntPtrHelper.ActionEsc();
|
||||
KeyIntPtrHelper.RaiseEscTwice();
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanCreate))]
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.ComponentModel;
|
||||
|
||||
namespace Sai.RvKits.RvMEP
|
||||
{
|
||||
public class SystemModel : ObservableObject
|
||||
public partial class SystemModel : ObservableObject
|
||||
{
|
||||
public SystemModel(MEPSystemType systemType)
|
||||
{
|
||||
@@ -19,75 +19,28 @@ namespace Sai.RvKits.RvMEP
|
||||
FillColor = systemType.FillColor;
|
||||
Abbreviation = systemType.Abbreviation;
|
||||
}
|
||||
|
||||
private string abbreviation;
|
||||
[ObservableProperty]
|
||||
private System.Windows.Media.Brush backgroundColor;
|
||||
|
||||
[ObservableProperty]
|
||||
private Color fillColor;
|
||||
private Color lineColor;
|
||||
|
||||
private MEPSystemClassification mepSystemClassification;
|
||||
[ObservableProperty]
|
||||
private MEPSystemClassification mEPSystemClassification;
|
||||
|
||||
[ObservableProperty]
|
||||
private string name;
|
||||
|
||||
[ObservableProperty]
|
||||
private PipeSystemType pipeSystemType;
|
||||
//系统类型
|
||||
[ObservableProperty]
|
||||
private MEPSystemType systemType;
|
||||
|
||||
public Color LineColor
|
||||
{
|
||||
get => lineColor;
|
||||
set => SetProperty(ref lineColor, value);
|
||||
}
|
||||
|
||||
public string Abbreviation
|
||||
{
|
||||
get => abbreviation;
|
||||
set => SetProperty(ref abbreviation, value);
|
||||
}
|
||||
|
||||
public Color FillColor
|
||||
{
|
||||
get => fillColor;
|
||||
set => SetProperty(ref fillColor, value);
|
||||
}
|
||||
|
||||
public PipeSystemType PipeSystemType
|
||||
{
|
||||
get => pipeSystemType;
|
||||
set => SetProperty(ref pipeSystemType, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统类型
|
||||
/// </summary>
|
||||
public MEPSystemType SystemType
|
||||
{
|
||||
get => systemType;
|
||||
set => SetProperty(ref systemType, value);
|
||||
}
|
||||
|
||||
public MEPSystemClassification MEPSystemClassification
|
||||
{
|
||||
get => mepSystemClassification;
|
||||
set => SetProperty(ref mepSystemClassification, value);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => name;
|
||||
set => SetProperty(ref name, value);
|
||||
}
|
||||
|
||||
public System.Windows.Media.Brush BackgroundColor
|
||||
{
|
||||
get => backgroundColor;
|
||||
//if (fillColor.IsValid)
|
||||
//{
|
||||
// return backgroundColor = new System.Windows.Media.SolidColorBrush(System.Windows.Media.SelectedColor.FromRgb(fillColor.Red, fillColor.Green, fillColor.Blue));
|
||||
//}
|
||||
//return backgroundColor = new System.Windows.Media.SolidColorBrush();
|
||||
set => SetProperty(ref backgroundColor, value);
|
||||
}
|
||||
[ObservableProperty]
|
||||
private Color lineColor;
|
||||
[ObservableProperty]
|
||||
private string abbreviation;
|
||||
|
||||
}
|
||||
|
||||
public enum MEPSystemClassification
|
||||
|
||||
Reference in New Issue
Block a user