Files
SzmediTools/Szmedi.RvKits/Drawing/MergeDimensionsCmd.cs

280 lines
10 KiB
C#
Raw Permalink Normal View History

2025-09-16 16:06:41 +08:00
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Nice3point.Revit.Toolkit.External;
using System;
using System.Collections;
using System.Linq;
namespace Szmedi.RvKits.DrawingTools;
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class MergeDimensionsCmd : ExternalCommand
{
public override void Execute()
{
MergeExecute(UiDocument);
//Result = Result.Succeeded;
}
public void MergeExecute(UIDocument uidoc)
{
var doc = uidoc.Document;
//视图中所有可见元素Id
var list = (
from e in new FilteredElementCollector(doc, doc.ActiveView.Id).WhereElementIsNotElementType()
select e.Id.IntegerValue
).ToList();
try
{
var selectedDims = uidoc.Selection
.PickElementsByRectangle(new GenericFilter<Dimension>(), "请框选尺寸标注")
.OfType<Dimension>()
.ToList();
var dictionary = new Dictionary<Line, List<Dimension>>();
foreach (Dimension dimension in selectedDims)
{
Line line = dimension.Curve as Line;
if (line != null)
{
bool flag = false;
foreach (var keyValuePair in dictionary)
{
bool flag3 =
(
Math.Abs(keyValuePair.Key.Origin.DistanceTo(line.Origin)) < 0.0001
&& Math.Abs(Math.Abs(keyValuePair.Key.Direction.DotProduct(line.Direction)) - 1.0) < 0.0001
)
|| Math.Abs(
Math.Abs(
keyValuePair.Key.Direction.DotProduct(Line.CreateBound(keyValuePair.Key.Origin, line.Origin).Direction)
) - 1.0
) < 0.0001;
if (flag3)
{
flag = true;
keyValuePair.Value.Add(dimension);
break;
}
}
if (!flag)
{
dictionary.Add(line, new List<Dimension> { dimension });
}
}
}
doc.InvokeGroup(_ =>
{
foreach (var keyValuePair in dictionary)
{
if (keyValuePair.Value.Count >= 1)
{
try
{
doc.Invoke(_ =>
{
ReferenceArray referenceArray = new();
View view = keyValuePair.Value.First().View;
DimensionType dimensionType = keyValuePair.Value.First().DimensionType;
List<DimData> dimsData = new();
foreach (Dimension dim in keyValuePair.Value)
{
if (dim.NumberOfSegments > 0)
{
dimsData.AddRange(from DimensionSegment segment in dim.Segments select new DimData(segment));
}
else
{
dimsData.Add(new DimData(dim));
}
foreach (Reference reference in dim.References)
{
bool flag8 =
reference.ElementId != ElementId.InvalidElementId
&& !list.Contains(reference.ElementId.IntegerValue);
if (!flag8 && reference.ElementId != ElementId.InvalidElementId)
{
if (doc.GetElement(reference.ElementId) is Grid grid)
{
referenceArray.Append(new Reference(grid));
}
else
{
if (reference.ElementId == ElementId.InvalidElementId)
{
continue;
}
referenceArray.Append(
doc.GetElement(reference.ElementId) is Level level ? new Reference(level) : reference
);
}
}
}
}
Dimension dimension3 = doc.Create.NewDimension(view, keyValuePair.Key, referenceArray, dimensionType);
if (dimension3 != null)
{
bool flag14 = TryRemoveZeroes(dimension3, out referenceArray);
if (flag14)
{
Dimension dimension4 = doc.Create.NewDimension(
view,
keyValuePair.Key,
referenceArray,
dimensionType
);
if (dimension4 != null)
{
doc.Delete(dimension3.Id);
RestoreTextFields(dimension4, dimsData);
}
}
else
{
RestoreTextFields(dimension3, dimsData);
}
doc.Delete((from d in keyValuePair.Value select d.Id).ToList());
}
});
}
catch (Exception)
{
// ignored
}
}
}
});
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
//break;
}
}
public static bool TryRemoveZeroes(Dimension dimension, out ReferenceArray referenceArray)
{
referenceArray = new ReferenceArray();
Document document = dimension.Document;
bool isEmpty = dimension.Segments.IsEmpty;
bool result;
if (isEmpty)
{
result = false;
}
else
{
for (int i = 0; i < dimension.NumberOfSegments; i++)
{
DimensionSegment dimensionSegment = dimension.Segments.get_Item(i);
double? value = dimensionSegment.Value;
bool flag = value != null && Math.Abs(value.Value) < 0.0001;
if (!flag)
{
bool isEmpty2 = referenceArray.IsEmpty;
if (isEmpty2)
{
var refer = dimension.References.get_Item(i);
Element element = document.GetElement(refer);
if (element is Grid or Level)
{
refer = new Reference(element);
}
referenceArray.Append(refer);
}
var refer1 = dimension.References.get_Item(i + 1);
Element element1 = document.GetElement(refer1);
if (element1 is Grid or Level)
{
refer1 = new Reference(element1);
}
referenceArray.Append(refer1);
}
}
result = referenceArray.Size < dimension.References.Size;
}
return result;
}
private static void RestoreTextFields(Dimension dimension, IReadOnlyCollection<DimData> dimsData)
{
IEnumerator enumerator = dimension.Segments.GetEnumerator();
while (enumerator.MoveNext())
{
DimensionSegment segment = (DimensionSegment)enumerator.Current;
DimData dimData = dimsData.FirstOrDefault(
d => d.IsMatchValue(segment?.Value) && Math.Abs(d.Origin.DistanceTo(segment.Origin)) < 0.0001
);
if (dimData != null && segment != null)
{
segment.Prefix = dimData.Prefix;
segment.Suffix = dimData.Suffix;
segment.Above = dimData.Above;
segment.Below = dimData.Below;
segment.TextPosition = dimData.TextPosition;
}
}
}
}
internal class DimData
{
public DimData(Dimension dimension)
{
Value = dimension.Value;
Origin = dimension.Origin;
TextPosition = dimension.TextPosition;
Prefix = dimension.Prefix;
Suffix = dimension.Suffix;
Above = dimension.Above;
Below = dimension.Below;
}
public DimData(DimensionSegment dimension)
{
Value = dimension.Value;
Origin = dimension.Origin;
TextPosition = dimension.TextPosition;
Prefix = dimension.Prefix;
Suffix = dimension.Suffix;
Above = dimension.Above;
Below = dimension.Below;
}
public double? Value { get; }
public string Prefix { get; }
public string Suffix { get; }
public string Above { get; }
public string Below { get; }
public XYZ Origin { get; }
public XYZ TextPosition { get; }
public bool IsMatchValue(double? value)
{
bool flag = Value != null && value != null;
bool result = flag ? Math.Abs(Value.Value - value.Value) < 0.0001 : Value == null && value == null;
return result;
}
}