280 lines
10 KiB
C#
280 lines
10 KiB
C#
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|