添加项目文件。
This commit is contained in:
41
Szmedi.RvKits/Drawing/CopyAnnotationViewModel.cs
Normal file
41
Szmedi.RvKits/Drawing/CopyAnnotationViewModel.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
namespace Szmedi.RvKits.DrawingTools;
|
||||
|
||||
public partial class CopyAnnotationViewModel : ObservableObject
|
||||
{
|
||||
public CopyAnnotationViewModel(UIApplication uiapp)
|
||||
{
|
||||
var doc = uiapp.ActiveUIDocument.Document;
|
||||
View3Ds = new FilteredElementCollector(doc).OfClass(typeof(View3D)).Cast<View3D>().Where(v => !v.IsTemplate);
|
||||
}
|
||||
[ObservableProperty]
|
||||
private IList<View3D> view3DsSelected;
|
||||
|
||||
[ObservableProperty] private IEnumerable view3Ds;
|
||||
|
||||
[RelayCommand]
|
||||
private void Confirm(object obj)
|
||||
{
|
||||
if (obj is Window window)
|
||||
{
|
||||
if (View3DsSelected is { Count: > 0 })
|
||||
{
|
||||
window.DialogResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SelectionChanged(object obj)
|
||||
{
|
||||
var type = obj.GetType();
|
||||
View3DsSelected = ((ObservableCollection<object>)obj).Cast<View3D>().ToList();
|
||||
}
|
||||
}
|
||||
37
Szmedi.RvKits/Drawing/CopyAnnotationWin.xaml
Normal file
37
Szmedi.RvKits/Drawing/CopyAnnotationWin.xaml
Normal file
@@ -0,0 +1,37 @@
|
||||
<controls:MaterialWindow
|
||||
x:Class="Szmedi.RvKits.DrawingTools.CopyAnnotationWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:controls="clr-namespace:Szmedi.RvKits.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Szmedi.RvKits.DrawingTools"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Title="复制标注"
|
||||
Width="300"
|
||||
Height="300"
|
||||
d:DataContext="{d:DesignInstance Type=local:CopyAnnotationViewModel}"
|
||||
|
||||
mc:Ignorable="d">
|
||||
<controls:MaterialWindow.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/Szmedi.RvKits;component/WPFUI.xaml" />
|
||||
</controls:MaterialWindow.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox DisplayMemberPath="Name" ItemsSource="{Binding View3Ds}" SelectionMode="Multiple">
|
||||
<b:Interaction.Triggers>
|
||||
<b:EventTrigger EventName="SelectionChanged">
|
||||
<b:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding SelectedItems, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}" />
|
||||
</b:EventTrigger>
|
||||
</b:Interaction.Triggers>
|
||||
</ListBox>
|
||||
<Button
|
||||
Grid.Row="1"
|
||||
Command="{Binding ConfirmCommand}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
|
||||
Content="完成" />
|
||||
</Grid>
|
||||
</controls:MaterialWindow>
|
||||
14
Szmedi.RvKits/Drawing/CopyAnnotationWin.xaml.cs
Normal file
14
Szmedi.RvKits/Drawing/CopyAnnotationWin.xaml.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Szmedi.RvKits.DrawingTools
|
||||
{
|
||||
/// <summary>
|
||||
/// CopyAnnotationWin.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CopyAnnotationWin
|
||||
{
|
||||
public CopyAnnotationWin(CopyAnnotationViewModel viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
422
Szmedi.RvKits/Drawing/Dimension2DTo3DCmd.cs
Normal file
422
Szmedi.RvKits/Drawing/Dimension2DTo3DCmd.cs
Normal file
@@ -0,0 +1,422 @@
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
|
||||
using System.Windows.Interop;
|
||||
|
||||
using Szmedi.RvKits.ModelManager;
|
||||
|
||||
namespace Szmedi.RvKits.DrawingTools;
|
||||
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
|
||||
public class Dimension2DTo3DCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
View viewPlan = Document.ActiveView;
|
||||
CopyAnnotationViewModel viewModel = new(UiApplication);
|
||||
CopyAnnotationWin win = null;
|
||||
//AssemblyLoaderHelpers loader = new(GlobalVariables.DirAssembly);
|
||||
//loader.HookAssemblyResolve();
|
||||
List<MessageModel> models = new();
|
||||
try
|
||||
{
|
||||
win = new CopyAnnotationWin(viewModel);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.Message);
|
||||
LogAssists.WriteLog(e.StackTrace);
|
||||
}
|
||||
//finally
|
||||
//{
|
||||
// loader.UnhookAssemblyResolve();
|
||||
//}
|
||||
|
||||
List<Dimension> dimensions = new FilteredElementCollector(Document, viewPlan.Id)
|
||||
.OfClass(typeof(Dimension))
|
||||
.WhereElementIsNotElementType()
|
||||
.Cast<Dimension>()
|
||||
.ToList();
|
||||
if (win != null && win.ShowDialog() == true)
|
||||
{
|
||||
if (win.DialogResult == true)
|
||||
{
|
||||
using TransactionGroup group = new(Document, "复制平面标注");
|
||||
group.Start();
|
||||
|
||||
foreach (View3D view3D in viewModel.View3DsSelected)
|
||||
{
|
||||
SketchPlane originSketch = view3D.SketchPlane;
|
||||
using (Transaction ts = new(Document, "复制尺寸标注"))
|
||||
{
|
||||
foreach (Dimension dimension in dimensions)
|
||||
{
|
||||
try
|
||||
{
|
||||
ts.Start();
|
||||
List<Reference> references = new();
|
||||
Curve curve = dimension.Curve;
|
||||
curve.MakeBound(0, 100);
|
||||
Plane plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, curve.GetEndPoint(0));
|
||||
view3D.SketchPlane = SketchPlane.Create(Document, plane);
|
||||
switch (dimension.DimensionShape)
|
||||
{
|
||||
case DimensionShape.Linear:
|
||||
bool isContainMepCurve = false;
|
||||
Curve locCurve = null;
|
||||
ReferenceArray array = new();
|
||||
foreach (Reference reference in dimension.References)
|
||||
{
|
||||
//重新定义参照平面为管线的平面
|
||||
if (Document.GetElement(reference) is MEPCurve mepCurve)
|
||||
{
|
||||
LocationCurve loc = mepCurve.Location as LocationCurve;
|
||||
locCurve = loc.Curve;
|
||||
plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, locCurve.GetEndPoint(0));
|
||||
view3D.SketchPlane = SketchPlane.Create(Document, plane);
|
||||
isContainMepCurve = true;
|
||||
if (reference.ConvertToStableRepresentation(Document).EndsWith(":0:LINEAR"))
|
||||
{
|
||||
array.Append(new Reference(mepCurve));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
array.Append(reference);
|
||||
}
|
||||
|
||||
if (isContainMepCurve)
|
||||
{
|
||||
double dis = locCurve.GetEndPoint(0).Z - curve.GetEndPoint(0).Z;
|
||||
Curve finalCurve = dimension.Curve.CreateTransformed(
|
||||
Transform.CreateTranslation(dis * XYZ.BasisZ)
|
||||
);
|
||||
Document.Create.NewDimension(view3D, finalCurve as Line, array, dimension.DimensionType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Document.Create.NewDimension(
|
||||
view3D,
|
||||
dimension.Curve as Line,
|
||||
dimension.References,
|
||||
dimension.DimensionType
|
||||
);
|
||||
//dim.Curve.CreateTransformed(Transform.CreateTranslation(10 * XYZ.BasisZ));
|
||||
}
|
||||
|
||||
//var elem = doc.GetElement(dimension.References.get_Item(0));
|
||||
break;
|
||||
case DimensionShape.Angular:
|
||||
foreach (Reference reference in dimension.References)
|
||||
{
|
||||
references.Add(reference);
|
||||
}
|
||||
|
||||
AngularDimension.Create(
|
||||
Document,
|
||||
view3D,
|
||||
dimension.Curve as Arc,
|
||||
references,
|
||||
dimension.DimensionType
|
||||
);
|
||||
break;
|
||||
case DimensionShape.Radial:
|
||||
break;
|
||||
case DimensionShape.ArcLength:
|
||||
break;
|
||||
case DimensionShape.Spot:
|
||||
int code = dimension.Category.GetHashCode();
|
||||
Reference refer = dimension.References.get_Item(0);
|
||||
if (code == -2000263) //高程点
|
||||
{
|
||||
SpotDimension spot = Document.Create.NewSpotElevation(
|
||||
view3D,
|
||||
refer,
|
||||
dimension.Origin,
|
||||
dimension.Origin,
|
||||
dimension.Origin,
|
||||
dimension.Origin,
|
||||
true
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code == -2000264) //坐标点
|
||||
{
|
||||
SpotDimension spot = Document.Create.NewSpotCoordinate(
|
||||
view3D,
|
||||
refer,
|
||||
dimension.Origin,
|
||||
dimension.Origin,
|
||||
dimension.Origin,
|
||||
dimension.Origin,
|
||||
true
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
case DimensionShape.Diameter:
|
||||
break;
|
||||
case DimensionShape.Unknown:
|
||||
break;
|
||||
}
|
||||
|
||||
ts.Commit();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
models.Add(new MessageModel(dimension, "无法复制"));
|
||||
if (ts.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
ts.Commit();
|
||||
}
|
||||
//TaskDialog.Show("错误", e.Message);
|
||||
}
|
||||
}
|
||||
//if (dimension.DimensionShape == DimensionShape.Radial)
|
||||
//{
|
||||
// continue;
|
||||
//}
|
||||
//if (dimension.DimensionShape == DimensionShape.Diameter)
|
||||
//{
|
||||
// continue;
|
||||
//}
|
||||
}
|
||||
|
||||
using (Transaction ts = new(Document, "重置工作平面"))
|
||||
{
|
||||
ts.Start();
|
||||
view3D.SketchPlane = originSketch;
|
||||
ts.Commit();
|
||||
}
|
||||
|
||||
using Transaction trans = new(Document, "复制标记");
|
||||
trans.Start();
|
||||
|
||||
bool canCopyTag = false;
|
||||
if (view3D.CanBeLocked() && view3D.CanSaveOrientation())
|
||||
{
|
||||
view3D.SaveOrientationAndLock();
|
||||
canCopyTag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxResult result = MessageBox.Show(
|
||||
"视图名存在意外的字符,族的标记将不会复制,是否继续?",
|
||||
"错误",
|
||||
MessageBoxButton.OKCancel,
|
||||
MessageBoxImage.Warning
|
||||
);
|
||||
if (result == MessageBoxResult.Cancel)
|
||||
{
|
||||
Result = Result.Cancelled;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<TextNote> textList = new FilteredElementCollector(Document, viewPlan.Id)
|
||||
.OfClass(typeof(TextNote))
|
||||
.ToElements()
|
||||
.Cast<TextNote>();
|
||||
IEnumerable<IndependentTag> tags = new FilteredElementCollector(Document, viewPlan.Id)
|
||||
.OfClass(typeof(IndependentTag))
|
||||
.ToElements()
|
||||
.Cast<IndependentTag>();
|
||||
foreach (TextNote text in textList)
|
||||
{
|
||||
XYZ position = text.Coord + (viewPlan.GenLevel.Elevation * XYZ.BasisZ);
|
||||
TextNoteOptions options =
|
||||
new()
|
||||
{
|
||||
KeepRotatedTextReadable = false,
|
||||
HorizontalAlignment = text.HorizontalAlignment,
|
||||
Rotation = 0,
|
||||
TypeId = text.TextNoteType.Id
|
||||
};
|
||||
TextNote note = TextNote.Create(Document, view3D.Id, position, text.Width, text.Text, options);
|
||||
note.SetFormattedText(text.GetFormattedText());
|
||||
note.LeaderLeftAttachment = text.LeaderLeftAttachment;
|
||||
note.LeaderRightAttachment = text.LeaderRightAttachment;
|
||||
}
|
||||
|
||||
//try
|
||||
//{
|
||||
if (canCopyTag)
|
||||
{
|
||||
foreach (IndependentTag tag in tags)
|
||||
{
|
||||
IndependentTag tagCopy;
|
||||
|
||||
double maxZ = Document.GetElement(tag.GetTaggedReference()).get_BoundingBox(view3D).Max.Z;
|
||||
|
||||
XYZ position = new(tag.TagHeadPosition.X, tag.TagHeadPosition.Y, maxZ);
|
||||
if (tag.IsOrphaned)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tagCopy = tag.IsMaterialTag
|
||||
? IndependentTag.Create(
|
||||
Document,
|
||||
view3D.Id,
|
||||
tag.GetTaggedReference(),
|
||||
tag.HasLeader,
|
||||
TagMode.TM_ADDBY_MATERIAL,
|
||||
tag.TagOrientation,
|
||||
position
|
||||
)
|
||||
: tag.IsMulticategoryTag
|
||||
? IndependentTag.Create(
|
||||
Document,
|
||||
view3D.Id,
|
||||
tag.GetTaggedReference(),
|
||||
tag.HasLeader,
|
||||
TagMode.TM_ADDBY_MULTICATEGORY,
|
||||
tag.TagOrientation,
|
||||
position
|
||||
)
|
||||
: IndependentTag.Create(
|
||||
Document,
|
||||
view3D.Id,
|
||||
tag.GetTaggedReference(),
|
||||
tag.HasLeader,
|
||||
TagMode.TM_ADDBY_CATEGORY,
|
||||
tag.TagOrientation,
|
||||
position
|
||||
);
|
||||
|
||||
tagCopy.ChangeTypeId(tag.GetTypeId());
|
||||
Document.Regenerate();
|
||||
|
||||
if (tagCopy.IsValidObject)
|
||||
{
|
||||
tagCopy.HasLeader = tag.HasLeader;
|
||||
if (tagCopy.HasLeader)
|
||||
{
|
||||
switch (tag.LeaderEndCondition)
|
||||
{
|
||||
case LeaderEndCondition.Attached:
|
||||
tagCopy.TagHeadPosition = position;
|
||||
break;
|
||||
case LeaderEndCondition.Free:
|
||||
tagCopy.TagHeadPosition = position;
|
||||
try
|
||||
{
|
||||
tagCopy.LeaderEnd = new XYZ(tag.LeaderEnd.X, tag.LeaderEnd.Y, maxZ);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogAssists.WriteLog(e.Message);
|
||||
models.Add(new MessageModel(tag, "无法修改引线端点值,需重建"));
|
||||
//stringBuilder.AppendLine($"{tag.Id.IntegerValue}");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tagCopy.CanLeaderEndConditionBeAssigned(tag.LeaderEndCondition))
|
||||
{
|
||||
tagCopy.LeaderEndCondition = tag.LeaderEndCondition;
|
||||
}
|
||||
|
||||
if (tag.HasLeader && tag.HasElbow)
|
||||
{
|
||||
tagCopy.LeaderElbow = new XYZ(tag.LeaderElbow.X, tag.LeaderElbow.Y, maxZ);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
models.Add(new MessageModel(tag, "无法复制"));
|
||||
//stringBuilder.AppendLine($"标注类型:{tag.Name},标注Id:{tag.Id.IntegerValue}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trans.Commit();
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// message = ex.InnerException.ToString();
|
||||
// if (trans.GetStatus() == TransactionStatus.Started)
|
||||
// {
|
||||
// trans.RollBack();
|
||||
// }
|
||||
// return Result.Failed;
|
||||
//}
|
||||
}
|
||||
|
||||
if (group.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
group.Assimilate();
|
||||
}
|
||||
|
||||
//if (sb.ToString().Length > 0)
|
||||
//{
|
||||
// var result = TaskDialog.Show("标注复制问题", "需要手动解决的标注:\n\n" + sb + "\n是否保存到桌面并打开?", TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No);
|
||||
// if (result == TaskDialogResult.Yes)
|
||||
// {
|
||||
// var filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
|
||||
// $"\\标注问题 {DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-ffff")}.txt";
|
||||
// File.WriteAllText(filePath
|
||||
// , sb.ToString());
|
||||
// System.Diagnostics.Process.Start(filePath);
|
||||
// }
|
||||
//}
|
||||
|
||||
if (models.Count > 0)
|
||||
{
|
||||
MessageWin messageWin = new() { DataContext = new MessageViewModel(UiDocument, models) };
|
||||
new WindowInteropHelper(messageWin) { Owner = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle };
|
||||
messageWin.Show();
|
||||
//var result = TaskDialog.Show("标记复制问题", "需要手动解决的标注:\n\n" + stringBuilder + "\n是否保存到桌面并打开?", TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No);
|
||||
//if (result == TaskDialogResult.Yes)
|
||||
//{
|
||||
// var filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
|
||||
// $"\\标注问题 {DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-ffff")}.txt";
|
||||
// File.WriteAllText(filePath
|
||||
// , stringBuilder.ToString());
|
||||
// System.Diagnostics.Process.Start(filePath);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustTextDirection(Document Document)
|
||||
{
|
||||
IEnumerable<TextNote> textList = new FilteredElementCollector(Document, Document.ActiveView.Id)
|
||||
.OfClass(typeof(TextNote))
|
||||
.ToElements()
|
||||
.Cast<TextNote>();
|
||||
using Transaction trans = new(Document, "调整文字朝向");
|
||||
foreach (TextNote text in textList)
|
||||
{
|
||||
try
|
||||
{
|
||||
trans.Start();
|
||||
text.KeepRotatedTextReadable = false;
|
||||
Document.Regenerate();
|
||||
text.KeepRotatedTextReadable = true;
|
||||
trans.Commit();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (trans.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
trans.RollBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
90
Szmedi.RvKits/Drawing/DimensionBy2LineCmd.cs
Normal file
90
Szmedi.RvKits/Drawing/DimensionBy2LineCmd.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI.Selection;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
using System;
|
||||
|
||||
|
||||
namespace Szmedi.RvKits.DrawingTools
|
||||
{
|
||||
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
||||
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
|
||||
public class DimensionBy2LineCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
#region RepeatExecute
|
||||
|
||||
using Transaction trans = new(Document, "标注");
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
ElementReferenceType referenceType1 = ElementReferenceType.REFERENCE_TYPE_LINEAR;
|
||||
Reference refer = UiDocument.Selection.PickObject(
|
||||
ObjectType.Edge,
|
||||
new ReferenceSelectionFilter(referenceType1),
|
||||
"请选择第一条边"
|
||||
);
|
||||
Reference refer1 = UiDocument.Selection.PickObject(
|
||||
ObjectType.Edge,
|
||||
new ReferenceSelectionFilter(referenceType1),
|
||||
"请选择第二条边"
|
||||
);
|
||||
Element e = UiDocument.Document.GetElement(refer);
|
||||
Element e1 = UiDocument.Document.GetElement(refer1);
|
||||
|
||||
var f = e.GetGeometryObjectFromReference(refer) as Edge;
|
||||
var f1 = e1.GetGeometryObjectFromReference(refer1) as Edge;
|
||||
var c1 = f.AsCurve();
|
||||
var c2 = f1.AsCurve();
|
||||
var p1 = c1.GetEndPoint(0);
|
||||
c2.MakeUnbound();
|
||||
var p2 = c2.Project(p1).XYZPoint;
|
||||
Line l = Line.CreateBound(p1, p2);
|
||||
ReferenceArray array = new();
|
||||
|
||||
array.Append(refer);
|
||||
array.Append(refer1);
|
||||
try
|
||||
{
|
||||
trans.Start();
|
||||
Document.Create.NewDimension(Document.ActiveView, l, array);
|
||||
trans.Commit();
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
|
||||
{
|
||||
var plane = Plane.CreateByThreePoints(
|
||||
f.AsCurve().GetEndPoint(0),
|
||||
f.AsCurve().GetEndPoint(1),
|
||||
f1.AsCurve().GetEndPoint(0)
|
||||
);
|
||||
var originSketch = Document.ActiveView.SketchPlane;
|
||||
Document.ActiveView.SketchPlane = SketchPlane.Create(Document, plane);
|
||||
Document.Create.NewDimension(Document.ActiveView, l, array);
|
||||
Document.ActiveView.SketchPlane = originSketch;
|
||||
trans.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
if (trans.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
trans.Commit();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//message = ex.InnerException.ToString();
|
||||
if (trans.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
trans.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion RepeatExecute
|
||||
}
|
||||
}
|
||||
}
|
||||
308
Szmedi.RvKits/Drawing/DimensionElemCmd.cs
Normal file
308
Szmedi.RvKits/Drawing/DimensionElemCmd.cs
Normal file
@@ -0,0 +1,308 @@
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI.Selection;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
using System;
|
||||
|
||||
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 DimensionElemCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
using Transaction transaction = new(Document, "标注对象");
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
transaction.Start();
|
||||
Reference refer = UiDocument.Selection.PickObject(ObjectType.Element, "请选择要标注的对象");
|
||||
Element e = UiDocument.Document.GetElement(refer);
|
||||
CreateDimensionsByFaces(Document, e);
|
||||
transaction.Commit();
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
if (transaction.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
transaction.RollBack();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorMessage = ex.Message;
|
||||
if (transaction.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
transaction.RollBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Face> GetElementFaces(Element elem)
|
||||
{
|
||||
List<Face> faces = new();
|
||||
Options option =
|
||||
new()
|
||||
{
|
||||
ComputeReferences = true,
|
||||
DetailLevel = ViewDetailLevel.Fine,
|
||||
IncludeNonVisibleObjects = true
|
||||
};
|
||||
GeometryElement geometry = elem.get_Geometry(option);
|
||||
|
||||
foreach (GeometryObject geomObj in geometry)
|
||||
{
|
||||
GeometryInstance geomInstance = geomObj as GeometryInstance;
|
||||
|
||||
if (geomInstance != null)
|
||||
{
|
||||
bool usesSymbolGeometry = elem is FamilyInstance && !(elem as FamilyInstance).HasModifiedGeometry();
|
||||
GeometryElement instanceGeometry = usesSymbolGeometry
|
||||
? geomInstance.GetSymbolGeometry()
|
||||
: geomInstance.GetInstanceGeometry();
|
||||
|
||||
foreach (GeometryObject instObj in instanceGeometry)
|
||||
{
|
||||
Solid instSolid = instObj as Solid;
|
||||
if (instSolid == null || instSolid.Faces.Size == 0 || instSolid.Edges.Size == 0 || instSolid.Volume < 0.0001)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (Face face in instSolid.Faces)
|
||||
{
|
||||
faces.Add(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Solid solid = geomObj as Solid;
|
||||
if (solid != null)
|
||||
{
|
||||
if (solid.Faces.Size == 0 || solid.Edges.Size == 0 || solid.Volume < 0.0001)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (Face face in solid.Faces)
|
||||
{
|
||||
faces.Add(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return faces;
|
||||
}
|
||||
|
||||
private void CreateDimensionsByFace(Document Document, Face face)
|
||||
{
|
||||
List<Line> lines = new();
|
||||
if (face.EdgeLoops.Size > 0)
|
||||
{
|
||||
foreach (CurveLoop loop in face.GetEdgesAsCurveLoops())
|
||||
{
|
||||
foreach (Curve curve in loop)
|
||||
{
|
||||
if (curve is Line)
|
||||
{
|
||||
lines.Add(curve as Line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Line line in lines)
|
||||
{
|
||||
ReferenceArray array = new();
|
||||
array.Append(line.GetEndPointReference(0));
|
||||
array.Append(line.GetEndPointReference(1));
|
||||
Document.Create.NewDimension(Document.ActiveView, line, array);
|
||||
}
|
||||
|
||||
//List<Line> l1 = new List<Line>();
|
||||
//List<List<Line>> l2 = new List<List<Line>>();
|
||||
//GetParallLineGroups(lines, lines.FirstOrDefault(), l1, l2);
|
||||
//foreach (List<Line> list in l2)
|
||||
//{
|
||||
// if (list.Count <= 1)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// ReferenceArray array = new ReferenceArray();
|
||||
// var p1 = list.FirstOrDefault().Evaluate(0.5, true);
|
||||
// var result = list.LastOrDefault().Project(p1);
|
||||
// var p2 = result.XYZPoint;
|
||||
// Line l = Line.CreateBound(p1, p2);
|
||||
// foreach (Line line in list)
|
||||
// {
|
||||
// array.Append(line.GetEndPointReference(0));
|
||||
// }
|
||||
|
||||
// doc.Create.NewDimension(doc.ActiveView, l, array);
|
||||
//}
|
||||
}
|
||||
|
||||
private void CreateDimensionsByFaces(Document Document, Element e)
|
||||
{
|
||||
List<Face> elementFaces = GetElementFaces(e);
|
||||
if (e is Wall w)
|
||||
{
|
||||
IEnumerable<ElementId> elementIds = w.FindInserts(true, false, false, false)
|
||||
.Where(id => Document.GetElement(id) is Opening);
|
||||
foreach (var id in elementIds)
|
||||
{
|
||||
var opening = Document.GetElement(id);
|
||||
elementFaces.AddRange(GetElementFaces(opening));
|
||||
}
|
||||
}
|
||||
|
||||
Location loc = e.Location;
|
||||
var bounding = e.get_BoundingBox(Document.ActiveView);
|
||||
|
||||
//if (loc == null)
|
||||
//{
|
||||
// MessageBox.Show("元素无法被标注");
|
||||
// return;
|
||||
//}
|
||||
|
||||
//if (loc is LocationCurve)
|
||||
//{
|
||||
// p = (loc as LocationCurve).Curve.GetEndPoint(0);
|
||||
//}
|
||||
//else if (loc is LocationPoint)
|
||||
//{
|
||||
// p = (loc as LocationPoint).Point;
|
||||
//}
|
||||
|
||||
List<List<Face>> groups = new();
|
||||
GetParallFaces(elementFaces, groups);
|
||||
foreach (List<Face> faces in groups)
|
||||
{
|
||||
XYZ p = bounding.Min;
|
||||
if (faces.Count <= 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var face = faces[0];
|
||||
var face1 = faces[faces.Count - 1];
|
||||
ReferenceArray array = new();
|
||||
foreach (var f in faces)
|
||||
{
|
||||
if (f.Reference == null)
|
||||
{
|
||||
//var elementIds = e.GetGeneratingElementIds(f);
|
||||
//var openingId = elementIds.FirstOrDefault();
|
||||
//var opening = doc.GetElement(openingId) as Opening;
|
||||
//var fa = opening.GetGeometryObjectFromReference(f.Reference);
|
||||
//if (fa != f)
|
||||
//{
|
||||
// array.Append(fa.Reference);
|
||||
//}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
array.Append(f.Reference);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Line line = null;
|
||||
if (face is not null and PlanarFace)
|
||||
{
|
||||
var pf = face as PlanarFace;
|
||||
var direction = pf.FaceNormal;
|
||||
if (direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero))
|
||||
{
|
||||
p += direction * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
p += direction.CrossProduct(XYZ.BasisZ) * 2;
|
||||
}
|
||||
|
||||
line = Line.CreateUnbound(p, direction);
|
||||
}
|
||||
|
||||
Document.Create.NewDimension(Document.ActiveView, line, array);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
private void GetParallFaces(List<Face> faces, List<List<Face>> groups)
|
||||
{
|
||||
var firstface = faces.FirstOrDefault();
|
||||
faces = faces.FindAll(face => face is PlanarFace);
|
||||
List<Face> group = new() { firstface };
|
||||
groups.Add(group);
|
||||
PlanarFace pf = firstface as PlanarFace;
|
||||
faces.Remove(firstface);
|
||||
|
||||
for (var i = faces.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (faces[i] is not PlanarFace)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var tempFace = faces[i] as PlanarFace;
|
||||
|
||||
if (tempFace.FaceNormal.CrossProduct(pf.FaceNormal).IsAlmostEqualTo(XYZ.Zero))
|
||||
{
|
||||
group.Add(tempFace);
|
||||
faces.Remove(tempFace);
|
||||
|
||||
//GetParallFaces(faces, tempFace, ZoomRBGroup, groups);
|
||||
}
|
||||
}
|
||||
|
||||
if (faces.Count >= 1)
|
||||
{
|
||||
GetParallFaces(faces, groups);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetParallLineGroups(List<Curve> lines, List<List<Curve>> groups)
|
||||
{
|
||||
var firstLine = lines.FirstOrDefault();
|
||||
lines = lines.FindAll(curve => curve is Line);
|
||||
List<Curve> group = new() { firstLine };
|
||||
groups.Add(group);
|
||||
Line pf = firstLine as Line;
|
||||
lines.Remove(firstLine);
|
||||
|
||||
for (var i = 0; i < lines.Count; i++)
|
||||
{
|
||||
if (lines[i] is not Line)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var tempLine = lines[i] as Line;
|
||||
|
||||
if (tempLine.Direction.CrossProduct(pf.Direction).IsAlmostEqualTo(XYZ.Zero))
|
||||
{
|
||||
group.Add(tempLine);
|
||||
lines.Remove(tempLine);
|
||||
|
||||
//GetParallFaces(faces, tempFace, ZoomRBGroup, groups);
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.Count >= 1)
|
||||
{
|
||||
GetParallLineGroups(lines, groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Szmedi.RvKits/Drawing/DimensionPointLineCmd.cs
Normal file
88
Szmedi.RvKits/Drawing/DimensionPointLineCmd.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.Selection;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
using System;
|
||||
|
||||
|
||||
namespace Szmedi.RvKits.DrawingTools
|
||||
{
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
|
||||
public class DimensionPointLineCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
using Transaction trans = new(Document, "点线标注");
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
ElementReferenceType referenceType1 = ElementReferenceType.REFERENCE_TYPE_LINEAR;
|
||||
ElementReferenceType referenceType2 = ElementReferenceType.REFERENCE_TYPE_NONE;
|
||||
Reference refer = UiDocument.Selection.PickObject(
|
||||
ObjectType.Edge,
|
||||
new ReferenceSelectionFilter(referenceType1),
|
||||
"请选择边"
|
||||
);
|
||||
Reference refer1 = UiDocument.Selection.PickObject(
|
||||
ObjectType.PointOnElement,
|
||||
new ReferenceSelectionFilter(referenceType2),
|
||||
"请选择点"
|
||||
);
|
||||
Element e = UiDocument.Document.GetElement(refer);
|
||||
|
||||
var f = e.GetGeometryObjectFromReference(refer) as Edge;
|
||||
var c1 = f.AsCurve();
|
||||
var p1 = refer1.GlobalPoint;
|
||||
c1.MakeUnbound();
|
||||
var p2 = c1.Project(p1).XYZPoint;
|
||||
Line l = Line.CreateBound(p1, p2);
|
||||
ReferenceArray array = new();
|
||||
|
||||
array.Append(refer);
|
||||
array.Append(refer1);
|
||||
try
|
||||
{
|
||||
trans.Start();
|
||||
Document.Create.NewDimension(Document.ActiveView, l, array);
|
||||
trans.Commit();
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
|
||||
{
|
||||
var plane = Plane.CreateByThreePoints(f.AsCurve().GetEndPoint(0), f.AsCurve().GetEndPoint(1), p1);
|
||||
var originSketch = Document.ActiveView.SketchPlane;
|
||||
Document.ActiveView.SketchPlane = SketchPlane.Create(Document, plane);
|
||||
Document.Create.NewDimension(Document.ActiveView, l, array);
|
||||
Document.ActiveView.SketchPlane = originSketch;
|
||||
trans.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
if (trans.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
trans.Commit();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message == "Invalid number of references.")
|
||||
{
|
||||
ErrorMessage = "选择的参考不可用于生成标注";
|
||||
}
|
||||
|
||||
if (trans.GetStatus() == TransactionStatus.Started)
|
||||
{
|
||||
trans.Commit();
|
||||
}
|
||||
|
||||
Result = Result.Failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
726
Szmedi.RvKits/Drawing/DimensionView3dCmd.cs
Normal file
726
Szmedi.RvKits/Drawing/DimensionView3dCmd.cs
Normal file
@@ -0,0 +1,726 @@
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Szmedi.RvKits.DrawingTools
|
||||
{
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
|
||||
public class DimensionView3dCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
ViewFamilyType viewFamilyType = new FilteredElementCollector(Document)
|
||||
.OfClass(typeof(ViewFamilyType))
|
||||
.Cast<ViewFamilyType>()
|
||||
.FirstOrDefault(t => t.ViewFamily == ViewFamily.ThreeDimensional);
|
||||
IEnumerable<Grid> grids = new FilteredElementCollector(Document).OfClass(typeof(Grid)).Cast<Grid>();
|
||||
View3D myView = null;
|
||||
int n = 100;
|
||||
if (!grids.Any())
|
||||
{
|
||||
Result = Result.Cancelled;
|
||||
return;
|
||||
}
|
||||
Document.Invoke(
|
||||
_ =>
|
||||
{
|
||||
if (viewFamilyType != null)
|
||||
{
|
||||
myView = View3D.CreateIsometric(Document, viewFamilyType.Id);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
myView.Name = $"三维轴测视图_{i}";
|
||||
break;
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.ArgumentException) { }
|
||||
}
|
||||
|
||||
myView.SaveOrientationAndLock();
|
||||
List<ModelCurve> mcurves = Create3dGrid(myView, grids);
|
||||
Document.Regenerate();
|
||||
CreateDimension(Document, myView, mcurves);
|
||||
},
|
||||
"三维标注"
|
||||
);
|
||||
|
||||
UiDocument.ActiveView = myView;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取族实例所有面(实际为族类型的所有面)
|
||||
/// </summary>
|
||||
/// <param name="instance"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static List<Face> GetFacesByFamilyInstance(FamilyInstance instance, Options options)
|
||||
{
|
||||
List<Face> faces = new();
|
||||
//根据打开的方式得到几何信息
|
||||
GeometryElement geometry = instance.get_Geometry(options);
|
||||
foreach (GeometryObject geomObj in geometry)
|
||||
{
|
||||
//geomObj为几何实例
|
||||
GeometryInstance geomInstance = geomObj as GeometryInstance;
|
||||
if (geomInstance == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
//族实例未修改过(连接,剪切,复制,扩展)
|
||||
bool usesSymbolGeometry = instance is not null && !instance.HasModifiedGeometry();
|
||||
bool bo = instance.HasModifiedGeometry();
|
||||
GeometryElement instanceGeometry = usesSymbolGeometry
|
||||
? geomInstance.GetSymbolGeometry()
|
||||
: geomInstance.GetInstanceGeometry();
|
||||
|
||||
if (instanceGeometry != null)
|
||||
{
|
||||
//instanceGeometry.GetTransformed();
|
||||
//从实例中找到实例的几何体
|
||||
foreach (GeometryObject instObj in instanceGeometry)
|
||||
{
|
||||
//三维的实体
|
||||
Solid instSolid = instObj as Solid;
|
||||
if (instSolid == null || instSolid.Faces.Size == 0 || instSolid.Edges.Size == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (Face face in instSolid.Faces)
|
||||
{
|
||||
faces.Add(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//geomObj为几何体
|
||||
Solid solid = geomObj as Solid;
|
||||
if (solid != null)
|
||||
{
|
||||
if (solid.Faces.Size == 0 || solid.Edges.Size == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (Face face in solid.Faces)
|
||||
{
|
||||
faces.Add(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return faces;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取元素侧面
|
||||
/// </summary>
|
||||
/// <param name="elem"></param>
|
||||
/// <returns></returns>
|
||||
public static List<Face> GetSideFacesByElement(Element elem)
|
||||
{
|
||||
Options opt = new() { ComputeReferences = true, DetailLevel = ViewDetailLevel.Fine };
|
||||
GeometryElement ge = elem.get_Geometry(opt);
|
||||
List<Face> lstpf = new();
|
||||
foreach (GeometryObject obj in ge)
|
||||
{
|
||||
Solid solid = obj as Solid;
|
||||
if (solid != null)
|
||||
{
|
||||
foreach (Face face in solid.Faces)
|
||||
{
|
||||
PlanarFace pf = face as PlanarFace;
|
||||
if (pf != null)
|
||||
{
|
||||
//点乘,即面的法向与Z轴始终垂直
|
||||
double dotp = pf.FaceNormal.DotProduct(XYZ.BasisZ);
|
||||
if (dotp is < 1.0e-09 and > (-1.0e-09)) //近似为0
|
||||
{
|
||||
lstpf.Add(pf);
|
||||
}
|
||||
//if (pf.FaceNormal.CrossProduct(wall.Orientation).IsZeroLength())
|
||||
//{
|
||||
// lstpf.Add(pf);
|
||||
//}
|
||||
}
|
||||
|
||||
CylindricalFace cy = face as CylindricalFace;
|
||||
if (cy != null)
|
||||
{
|
||||
lstpf.Add(cy);
|
||||
}
|
||||
}
|
||||
|
||||
return lstpf;
|
||||
}
|
||||
}
|
||||
|
||||
return lstpf;
|
||||
}
|
||||
|
||||
private List<ModelCurve> Create3dGrid(View view, IEnumerable<Grid> grids)
|
||||
{
|
||||
Document Document = view.Document;
|
||||
List<TextNoteType> textnotetypes = new FilteredElementCollector(Document)
|
||||
.OfClass(typeof(TextNoteType))
|
||||
.Cast<TextNoteType>()
|
||||
.ToList();
|
||||
TextNoteType textnotetype = textnotetypes.FirstOrDefault();
|
||||
List<ModelCurve> curves = new();
|
||||
IEnumerable<bool> gridGroups = grids
|
||||
.GroupBy(g => g.Curve.ComputeDerivatives(0, true).BasisX.Normalize().X)
|
||||
.Select(s => s.Count() > 1);
|
||||
|
||||
Plane plane = Plane.CreateByOriginAndBasis(XYZ.Zero, XYZ.BasisX, XYZ.BasisY);
|
||||
SketchPlane sketch = SketchPlane.Create(Document, plane);
|
||||
|
||||
foreach (Grid grid in grids)
|
||||
{
|
||||
Curve curve = grid.Curve;
|
||||
XYZ startp = curve.GetEndPoint(0);
|
||||
XYZ endp = curve.GetEndPoint(1);
|
||||
|
||||
int radius = 2;
|
||||
XYZ direction = curve.ComputeDerivatives(0, true).BasisX.Normalize().Negate();
|
||||
XYZ direction1 = curve.ComputeDerivatives(1, true).BasisX.Normalize();
|
||||
SketchPlane gridSketch = SketchPlane.Create(Document, new Reference(grid));
|
||||
XYZ loc = startp + (direction * radius);
|
||||
XYZ loc1 = endp + (direction1 * radius);
|
||||
|
||||
Arc circle = Arc.Create(loc, radius, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY);
|
||||
Arc circle1 = Arc.Create(loc1, radius, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY);
|
||||
|
||||
TextNoteOptions options =
|
||||
new(textnotetype.Id)
|
||||
{
|
||||
HorizontalAlignment = HorizontalTextAlignment.Center,
|
||||
#if REVIT2019 || REVIT2020
|
||||
VerticalAlignment = VerticalTextAlignment.Middle
|
||||
#endif
|
||||
};
|
||||
//Text.FromStringOriginAndScale(grid.Name, loc, size);
|
||||
//Text.FromStringOriginAndScale(grid.Name, loc1, size);
|
||||
TextNote.Create(Document, view.Id, loc, grid.Name, options);
|
||||
TextNote.Create(Document, view.Id, loc1, grid.Name, options);
|
||||
|
||||
ModelCurve gridLine = Document.Create.NewModelCurve(grid.Curve, gridSketch);
|
||||
Document.Create.NewModelCurve(circle, sketch);
|
||||
Document.Create.NewModelCurve(circle1, sketch);
|
||||
curves.Add(gridLine);
|
||||
}
|
||||
|
||||
return curves;
|
||||
}
|
||||
|
||||
internal static MethodInfo GenerateTransientDisplayMethod()
|
||||
{
|
||||
Type geometryElementType = typeof(GeometryElement);
|
||||
MethodInfo[] geometryElementTypeMethods = geometryElementType.GetMethods(
|
||||
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic
|
||||
);
|
||||
MethodInfo method = geometryElementTypeMethods.FirstOrDefault(x => x.Name == "SetForTransientDisplay");
|
||||
return method;
|
||||
}
|
||||
|
||||
private ReferenceArray RemoveZeroSegements(Wall wall, ReferenceArray wallLengthRefernceArray, Dimension lengthdim)
|
||||
{
|
||||
List<Reference> referencesdelete = new();
|
||||
ReferenceArray finallengthreferenceArray = new();
|
||||
for (int i = 0; i < lengthdim.NumberOfSegments; i++)
|
||||
{
|
||||
if (lengthdim.Segments.get_Item(i).ValueString == "0")
|
||||
{
|
||||
if (lengthdim.References.get_Item(i).ElementId == wall.Id)
|
||||
{
|
||||
referencesdelete.Add(lengthdim.References.get_Item(i));
|
||||
}
|
||||
|
||||
if (lengthdim.References.get_Item(i + 1).ElementId == wall.Id)
|
||||
{
|
||||
referencesdelete.Add(lengthdim.References.get_Item(i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < wallLengthRefernceArray.Size; i++)
|
||||
{
|
||||
bool isContain = false;
|
||||
Reference reference = wallLengthRefernceArray.get_Item(i);
|
||||
foreach (Reference referdelete in referencesdelete)
|
||||
{
|
||||
if (reference.EqualTo(referdelete))
|
||||
{
|
||||
isContain = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isContain)
|
||||
{
|
||||
finallengthreferenceArray.Append(reference);
|
||||
}
|
||||
}
|
||||
|
||||
return finallengthreferenceArray;
|
||||
}
|
||||
|
||||
public void CreateBeamsDimension(Document Document)
|
||||
{
|
||||
FilteredElementCollector col = new(Document, Document.ActiveView.Id);
|
||||
ElementCategoryFilter categoryFilter1 = new(BuiltInCategory.OST_StructuralFraming);
|
||||
col.WherePasses(categoryFilter1);
|
||||
IEnumerable<Element> beams = col.GroupBy(g => g.Name).Select(s => s.FirstOrDefault());
|
||||
|
||||
foreach (FamilyInstance familyInstance in beams)
|
||||
{
|
||||
XYZ loc = (familyInstance.Location as LocationPoint).Point;
|
||||
List<Face> faces = GetSideFacesByElement(familyInstance);
|
||||
if (faces.Count == 0) //找不到实例的几何元素时,需从类型集合查找
|
||||
{
|
||||
Options options = new() { ComputeReferences = true };
|
||||
faces = GetFacesByFamilyInstance(familyInstance, options);
|
||||
for (int i = faces.Count - 1; i >= 0; i--)
|
||||
{
|
||||
PlanarFace pf = faces[i] as PlanarFace;
|
||||
if (pf.FaceNormal.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero))
|
||||
{
|
||||
faces.Remove(faces[i]); //移除顶面底面
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceArray referenceArray = new();
|
||||
ReferenceArrayArray referenceArrayArray = new();
|
||||
GetParallFacesReferenceArray(faces, faces.FirstOrDefault(), referenceArray, referenceArrayArray);
|
||||
foreach (ReferenceArray array in referenceArrayArray)
|
||||
{
|
||||
PlanarFace face = familyInstance.GetGeometryObjectFromReference(array.get_Item(0)) as PlanarFace;
|
||||
Line line = Line.CreateUnbound(loc, face.FaceNormal).CreateOffset(600 / 304.8, XYZ.BasisZ) as Line;
|
||||
Document.Create.NewDimension(Document.ActiveView, line, array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateColumnsDimension(Document Document, View view)
|
||||
{
|
||||
FilteredElementCollector col = new(Document, view.Id);
|
||||
ElementCategoryFilter categoryFilter1 = new(BuiltInCategory.OST_StructuralColumns);
|
||||
ElementCategoryFilter categoryFilter2 = new(BuiltInCategory.OST_Columns);
|
||||
LogicalOrFilter andFilter = new(categoryFilter1, categoryFilter2);
|
||||
col.WherePasses(andFilter);
|
||||
IEnumerable<Element> columns = col.GroupBy(g => g.Name).Select(s => s.FirstOrDefault());
|
||||
|
||||
foreach (FamilyInstance familyInstance in columns)
|
||||
{
|
||||
XYZ loc = (familyInstance.Location as LocationPoint).Point;
|
||||
List<Face> faces = GetSideFacesByElement(familyInstance);
|
||||
if (faces.Count == 0) //找不到实例的几何元素时,需从类型集合查找
|
||||
{
|
||||
Options options = new() { ComputeReferences = true };
|
||||
faces = GetFacesByFamilyInstance(familyInstance, options);
|
||||
for (int i = faces.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (faces[i] is PlanarFace)
|
||||
{
|
||||
PlanarFace pf = faces[i] as PlanarFace;
|
||||
if (pf.FaceNormal.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero))
|
||||
{
|
||||
faces.Remove(faces[i]); //移除顶面底面
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceArray referenceArray = new();
|
||||
ReferenceArrayArray referenceArrayArray = new();
|
||||
GetParallFacesReferenceArray(faces, faces.FirstOrDefault(), referenceArray, referenceArrayArray);
|
||||
foreach (ReferenceArray array in referenceArrayArray)
|
||||
{
|
||||
if (array.Size == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PlanarFace face = familyInstance.GetGeometryObjectFromReference(array.get_Item(0)) as PlanarFace;
|
||||
Line line = Line.CreateUnbound(loc, face.FaceNormal).CreateOffset(600 / 304.8, XYZ.BasisZ) as Line;
|
||||
Document.Create.NewDimension(Document.ActiveView, line, array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateDimension(Document Document, View view, List<ModelCurve> mcurves)
|
||||
{
|
||||
List<Curve> lines = mcurves.Where(c => c is ModelLine).Select(mc => mc.GeometryCurve).ToList();
|
||||
|
||||
List<List<Curve>> groups = new();
|
||||
GetParallLineGroups(lines, groups);
|
||||
foreach (List<Curve> g in groups)
|
||||
{
|
||||
List<Line> gx = g.ConvertAll(x => x as Line);
|
||||
if (!gx.Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
XYZ direction = gx.FirstOrDefault()?.Direction;
|
||||
//IOrderedEnumerable<Line> orderedlist = null;
|
||||
//if (direction.AngleTo(XYZ.BasisX) >= direction.AngleTo(XYZ.BasisY))
|
||||
//{
|
||||
// orderedlist = gx.OrderBy(l => l.Direction.X);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// orderedlist = gx.OrderBy(l => l.Direction.Y);
|
||||
//}
|
||||
|
||||
if (g.Count <= 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Line line =
|
||||
Line.CreateUnbound(g.FirstOrDefault()?.GetEndPoint(0), direction.CrossProduct(XYZ.BasisZ))
|
||||
.CreateOffset(1500 / 304.8, XYZ.BasisZ) as Line;
|
||||
Line line1 =
|
||||
Line.CreateUnbound(g.FirstOrDefault()?.GetEndPoint(1), direction.CrossProduct(XYZ.BasisZ))
|
||||
.CreateOffset(1500 / 304.8, XYZ.BasisZ) as Line;
|
||||
ReferenceArray arrayAll = new();
|
||||
foreach (Curve l in g)
|
||||
{
|
||||
arrayAll.Append(l.Reference);
|
||||
}
|
||||
|
||||
Dimension dimension1 = Document.Create.NewDimension(view, line, arrayAll);
|
||||
Dimension dimension2 = Document.Create.NewDimension(view, line1, arrayAll);
|
||||
Document.Regenerate();
|
||||
Line line3 =
|
||||
Line.CreateUnbound(g.FirstOrDefault()?.GetEndPoint(0), direction.CrossProduct(XYZ.BasisZ))
|
||||
.CreateOffset(1000 / 304.8, XYZ.BasisZ) as Line;
|
||||
Line line4 =
|
||||
Line.CreateUnbound(g.FirstOrDefault()?.GetEndPoint(1), direction.CrossProduct(XYZ.BasisZ))
|
||||
.CreateOffset(1000 / 304.8, XYZ.BasisZ) as Line;
|
||||
|
||||
ReferenceArray array = new();
|
||||
array.Append(dimension1.References.get_Item(0));
|
||||
array.Append(dimension1.References.get_Item(arrayAll.Size - 1));
|
||||
Document.Create.NewDimension(view, line3, array);
|
||||
Document.Create.NewDimension(view, line4, array);
|
||||
Document.Regenerate();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateWallDimension(Document Document, View view)
|
||||
{
|
||||
FilteredElementCollector wallCol = new FilteredElementCollector(Document, view.Id).OfClass(typeof(Wall));
|
||||
|
||||
foreach (Wall wall in wallCol)
|
||||
{
|
||||
if (wall.WallType.Kind != WallKind.Basic)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LocationCurve loc = wall.Location as LocationCurve;
|
||||
ReferenceArray wallThickReferenceArray = new();
|
||||
ReferenceArray wallLengthRefernceArray = new();
|
||||
List<Face> faces = GetSideFacesByElement(wall);
|
||||
|
||||
foreach (Face face in faces)
|
||||
{
|
||||
PlanarFace pf = face as PlanarFace;
|
||||
if (pf == null || face.Reference == null || pf.OrientationMatchesSurfaceOrientation == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pf.FaceNormal.CrossProduct(wall.Orientation).IsAlmostEqualTo(XYZ.Zero))
|
||||
{
|
||||
if (Document.GetElement(face.Reference).Id == wall.Id)
|
||||
{
|
||||
wallThickReferenceArray.Append(face.Reference);
|
||||
}
|
||||
}
|
||||
else if (pf.FaceNormal.DotProduct(wall.Orientation) < 0.001)
|
||||
{
|
||||
wallLengthRefernceArray.Append(face.Reference);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int scale = Document.ActiveView.Scale;
|
||||
Autodesk.Revit.DB.Transform tranform = Autodesk.Revit.DB.Transform.CreateTranslation(
|
||||
wall.Orientation * scale * 15 / 304.8
|
||||
);
|
||||
Line wallcurve = (wall.Location as LocationCurve).Curve as Line;
|
||||
Line lengthLine = wallcurve.CreateTransformed(tranform) as Line;
|
||||
Dimension lengthdim = Document.Create.NewDimension(Document.ActiveView, lengthLine, wallLengthRefernceArray);
|
||||
Document.Regenerate();
|
||||
|
||||
ReferenceArray finallengthreferenceArray = RemoveZeroSegements(wall, wallLengthRefernceArray, lengthdim);
|
||||
Document.Delete(lengthdim.Id);
|
||||
Document.Create.NewDimension(Document.ActiveView, lengthLine, finallengthreferenceArray);
|
||||
|
||||
Line thickLine = Line.CreateUnbound(wallcurve.Evaluate(0.2, true), wall.Orientation);
|
||||
Dimension thickdim = Document.Create.NewDimension(Document.ActiveView, thickLine, wallThickReferenceArray);
|
||||
|
||||
if (lengthdim.Segments.Size > 2)
|
||||
{
|
||||
ReferenceArray referenceArray = new();
|
||||
Reference refer1 = lengthdim.References.get_Item(0);
|
||||
Reference refer2 = lengthdim.References.get_Item(lengthdim.References.Size - 1);
|
||||
referenceArray.Append(refer1);
|
||||
referenceArray.Append(refer2);
|
||||
Autodesk.Revit.DB.Transform tranform1 = Autodesk.Revit.DB.Transform.CreateTranslation(
|
||||
wall.Orientation * scale * 25 / 304.8
|
||||
);
|
||||
Line lengthLine1 = wallcurve.CreateTransformed(tranform1) as Line;
|
||||
|
||||
Document.Create.NewDimension(Document.ActiveView, lengthLine1, referenceArray);
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
public void GetParallFacesReferenceArray(
|
||||
List<Face> faces,
|
||||
Face firstFace,
|
||||
ReferenceArray referenceArray,
|
||||
ReferenceArrayArray referenceArrayArray
|
||||
)
|
||||
{
|
||||
if (referenceArrayArray.Size == 0)
|
||||
{
|
||||
referenceArrayArray.Append(referenceArray);
|
||||
}
|
||||
|
||||
for (int i = 0; i < faces.Count; i++)
|
||||
{
|
||||
if (faces[i] is not PlanarFace)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PlanarFace tempFace = faces[i] as PlanarFace;
|
||||
PlanarFace pf = firstFace as PlanarFace;
|
||||
XYZ facenormal = pf.FaceNormal;
|
||||
//把初始的第一个添加进集合
|
||||
|
||||
if (tempFace.FaceNormal.CrossProduct(facenormal).IsAlmostEqualTo(XYZ.Zero))
|
||||
{
|
||||
referenceArray.Append(tempFace.Reference);
|
||||
faces.Remove(tempFace);
|
||||
GetParallFacesReferenceArray(faces, tempFace, referenceArray, referenceArrayArray);
|
||||
}
|
||||
|
||||
if (i == faces.Count() - 1)
|
||||
{
|
||||
referenceArray = new ReferenceArray();
|
||||
GetParallFacesReferenceArray(faces, faces.FirstOrDefault(), referenceArray, referenceArrayArray);
|
||||
if (!faces.Any())
|
||||
{
|
||||
referenceArrayArray.Append(referenceArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归找到所有平行线集合
|
||||
/// </summary>
|
||||
public static void GetParallLineGroups(List<Curve> lines, List<List<Curve>> groups)
|
||||
{
|
||||
Curve firstLine = lines.FirstOrDefault();
|
||||
lines = lines.FindAll(curve => curve is Line);
|
||||
List<Curve> group = new() { firstLine };
|
||||
groups.Add(group);
|
||||
Line line = firstLine as Line;
|
||||
lines.Remove(firstLine);
|
||||
|
||||
for (int i = lines.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (lines[i] is not Line)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Line tempLine = lines[i] as Line;
|
||||
|
||||
if (
|
||||
tempLine.Direction.CrossProduct(line.Direction).IsAlmostEqualTo(XYZ.Zero)
|
||||
&& Math.Abs(tempLine.Length - line.Length) < 0.00001
|
||||
)
|
||||
{
|
||||
group.Add(tempLine);
|
||||
lines.Remove(tempLine);
|
||||
|
||||
//GetParallFaces(faces, tempFace, ZoomRBGroup, groups);
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.Count >= 1)
|
||||
{
|
||||
GetParallLineGroups(lines, groups);
|
||||
}
|
||||
}
|
||||
|
||||
private void TransientGrid(Document Document, Grid grid)
|
||||
{
|
||||
double radius = 1.5;
|
||||
double size = 1.8;
|
||||
XYZ startp = grid.Curve.GetEndPoint(0);
|
||||
XYZ endp = grid.Curve.GetEndPoint(1);
|
||||
XYZ direction = grid.Curve.ComputeDerivatives(0, true).BasisX.Normalize().Negate();
|
||||
XYZ direction1 = grid.Curve.ComputeDerivatives(1, true).BasisX.Normalize();
|
||||
XYZ loc = startp + (direction * radius);
|
||||
XYZ loc1 = endp + (direction1 * radius);
|
||||
|
||||
IEnumerable<Curve> text = Text.FromStringOriginAndScale(grid.Name, loc, size);
|
||||
IEnumerable<Curve> text1 = Text.FromStringOriginAndScale(grid.Name, loc1, size);
|
||||
|
||||
Arc circle = Arc.Create(loc, radius, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY);
|
||||
Arc circle1 = Arc.Create(loc1, radius, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY);
|
||||
List<GeometryObject> geoms = new() { grid.Curve, circle, circle1 };
|
||||
geoms.AddRange(text);
|
||||
geoms.AddRange(text1);
|
||||
MethodInfo method = GenerateTransientDisplayMethod();
|
||||
object[] argsM = new object[4];
|
||||
argsM[0] = Document;
|
||||
argsM[1] = ElementId.InvalidElementId;
|
||||
argsM[2] = geoms;
|
||||
argsM[3] = ElementId.InvalidElementId;
|
||||
ElementId transientElementId = (ElementId)method.Invoke(null, argsM);
|
||||
MessageBox.Show(transientElementId.IntegerValue.ToString(), "元素ID");
|
||||
//doc.Delete(transientElementId);
|
||||
}
|
||||
}
|
||||
|
||||
public class TransientElementMaker : ITransientElementMaker
|
||||
{
|
||||
private readonly Document _document;
|
||||
|
||||
public List<GeometryObject> GeometryObjects { get; set; }
|
||||
|
||||
public TransientElementMaker(Document document)
|
||||
{
|
||||
_document = document;
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
if (GeometryObjects != null)
|
||||
{
|
||||
DirectShape ds = DirectShape.CreateElement(_document, new ElementId(BuiltInCategory.OST_GenericModel));
|
||||
//CreateUtils.CreateCube(), CreateUtils.CreateSphere()为创建一个立方体与球体Solid,文略
|
||||
//ds.AppendShape(GeometryObjects);
|
||||
ds.AppendShape(new List<GeometryObject> { CreateCube() });
|
||||
}
|
||||
}
|
||||
|
||||
public Solid CreateCube()
|
||||
{
|
||||
CurveLoop cubeBaseLines = new();
|
||||
cubeBaseLines.Append(Line.CreateBound(new XYZ(0, 0, 0), new XYZ(100, 0, 0)));
|
||||
cubeBaseLines.Append(Line.CreateBound(new XYZ(100, 0, 0), new XYZ(100, 100, 0)));
|
||||
cubeBaseLines.Append(Line.CreateBound(new XYZ(100, 100, 0), new XYZ(0, 100, 0)));
|
||||
cubeBaseLines.Append(Line.CreateBound(new XYZ(0, 100, 0), new XYZ(0, 0, 0)));
|
||||
Solid solidCube = GeometryCreationUtilities.CreateExtrusionGeometry(new List<CurveLoop> { cubeBaseLines }, XYZ.BasisZ, 100);
|
||||
|
||||
return solidCube;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Text
|
||||
{
|
||||
public static IEnumerable<Curve> FromStringOriginAndScale(string text, XYZ origin, double scale)
|
||||
{
|
||||
//http://msdn.microsoft.com/en-us/library/ms745816(v=vs.110).aspx
|
||||
|
||||
List<Curve> crvs = new();
|
||||
|
||||
FontFamily font = new("Arial");
|
||||
FontStyle fontStyle = FontStyles.Normal;
|
||||
FontWeight fontWeight = FontWeights.Medium;
|
||||
|
||||
//if (Bold == true) fontWeight = FontWeights.Bold;
|
||||
//if (Italic == true) fontStyle = FontStyles.Italic;
|
||||
|
||||
// Create the formatted text based on the properties set.
|
||||
#if REVIT2019||REVIT2020
|
||||
System.Windows.Media.FormattedText formattedText =
|
||||
new(
|
||||
text,
|
||||
CultureInfo.GetCultureInfo("en-us"),
|
||||
FlowDirection.LeftToRight,
|
||||
new Typeface(font, fontStyle, fontWeight, FontStretches.Normal),
|
||||
1,
|
||||
Brushes.Black,
|
||||
1 // This brush does not matter since we use the geometry of the text.
|
||||
);
|
||||
#elif REVIT2018
|
||||
var formattedText = new System.Windows.Media.FormattedText(
|
||||
text,
|
||||
CultureInfo.GetCultureInfo("en-us"),
|
||||
FlowDirection.LeftToRight,
|
||||
new Typeface(font, fontStyle, fontWeight, FontStretches.Normal),
|
||||
1,
|
||||
Brushes.Black // This brush does not matter since we use the geometry of the text.
|
||||
,
|
||||
1.25
|
||||
);
|
||||
#endif
|
||||
// Build the geometry object that represents the text.
|
||||
Geometry textGeometry = formattedText.BuildGeometry(new System.Windows.Point(0, 0));
|
||||
foreach (PathFigure figure in textGeometry.GetFlattenedPathGeometry().Figures)
|
||||
{
|
||||
System.Windows.Point init = figure.StartPoint;
|
||||
System.Windows.Point a = figure.StartPoint;
|
||||
System.Windows.Point b;
|
||||
foreach (PathSegment segment in figure.GetFlattenedPathFigure().Segments)
|
||||
{
|
||||
if (segment is System.Windows.Media.LineSegment lineSeg)
|
||||
{
|
||||
b = lineSeg.Point;
|
||||
Line crv = LineBetweenPoints(origin, scale, a, b);
|
||||
a = b;
|
||||
crvs.Add(crv);
|
||||
}
|
||||
|
||||
if (segment is PolyLineSegment plineSeg)
|
||||
{
|
||||
foreach (System.Windows.Point segPt in plineSeg.Points)
|
||||
{
|
||||
Line crv = LineBetweenPoints(origin, scale, a, segPt);
|
||||
a = segPt;
|
||||
crvs.Add(crv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return crvs;
|
||||
}
|
||||
|
||||
private static Line LineBetweenPoints(XYZ origin, double scale, System.Windows.Point a, System.Windows.Point b)
|
||||
{
|
||||
XYZ pt1 = new((a.X * scale) + origin.X, ((-a.Y + 1) * scale) + origin.Y, origin.Z);
|
||||
XYZ pt2 = new((b.X * scale) + origin.X, ((-b.Y + 1) * scale) + origin.Y, origin.Z);
|
||||
Line crv = Line.CreateBound(pt1, pt2);
|
||||
return crv;
|
||||
}
|
||||
}
|
||||
}
|
||||
279
Szmedi.RvKits/Drawing/MergeDimensionsCmd.cs
Normal file
279
Szmedi.RvKits/Drawing/MergeDimensionsCmd.cs
Normal file
@@ -0,0 +1,279 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
117
Szmedi.RvKits/Drawing/SplitDimensionsCmd.cs
Normal file
117
Szmedi.RvKits/Drawing/SplitDimensionsCmd.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
using System;
|
||||
|
||||
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 SplitDimensionsCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
SplitExecute(UiDocument);
|
||||
}
|
||||
|
||||
public void SplitExecute(UIDocument uidoc)
|
||||
{
|
||||
var doc = uidoc.Document;
|
||||
try
|
||||
{
|
||||
List<Dimension> list = uidoc.Selection
|
||||
.PickElementsByRectangle(new GenericFilter<Dimension>(), "框选尺寸标注")
|
||||
.OfType<Dimension>()
|
||||
.ToList();
|
||||
bool flag = !list.Any();
|
||||
if (!flag)
|
||||
{
|
||||
doc.InvokeGroup(
|
||||
transactionGroup =>
|
||||
{
|
||||
foreach (Dimension dimension in list)
|
||||
{
|
||||
try
|
||||
{
|
||||
Line line = dimension.Curve as Line;
|
||||
if (line != null)
|
||||
{
|
||||
doc.Invoke(ts =>
|
||||
{
|
||||
for (int i = 0; i < dimension.NumberOfSegments; i++)
|
||||
{
|
||||
DimensionSegment dimensionSegment = dimension.Segments.get_Item(i);
|
||||
Reference reference = dimension.References.get_Item(i);
|
||||
if (reference.ElementId != ElementId.InvalidElementId)
|
||||
{
|
||||
if (doc.GetElement(reference.ElementId) is Grid grid)
|
||||
{
|
||||
reference = new Reference(grid);
|
||||
}
|
||||
}
|
||||
|
||||
if (reference.ElementId != ElementId.InvalidElementId)
|
||||
{
|
||||
if (doc.GetElement(reference.ElementId) is Level level)
|
||||
{
|
||||
reference = new Reference(level);
|
||||
}
|
||||
}
|
||||
|
||||
Reference reference2 = dimension.References.get_Item(i + 1);
|
||||
if (reference2.ElementId != ElementId.InvalidElementId)
|
||||
{
|
||||
if (doc.GetElement(reference2.ElementId) is Grid grid2)
|
||||
{
|
||||
reference2 = new Reference(grid2);
|
||||
}
|
||||
}
|
||||
|
||||
if (reference2.ElementId != ElementId.InvalidElementId)
|
||||
{
|
||||
if (doc.GetElement(reference2.ElementId) is Level level2)
|
||||
{
|
||||
reference2 = new Reference(level2);
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceArray referenceArray = new();
|
||||
referenceArray.Append(reference);
|
||||
referenceArray.Append(reference2);
|
||||
Dimension dimension2 = doc.Create.NewDimension(
|
||||
dimension.View,
|
||||
line,
|
||||
referenceArray,
|
||||
dimension.DimensionType
|
||||
);
|
||||
if (dimension2 != null)
|
||||
{
|
||||
dimension2.Prefix = dimensionSegment.Prefix;
|
||||
dimension2.Suffix = dimensionSegment.Suffix;
|
||||
dimension2.Above = dimensionSegment.Above;
|
||||
dimension2.Below = dimensionSegment.Below;
|
||||
dimension2.TextPosition = dimensionSegment.TextPosition;
|
||||
}
|
||||
}
|
||||
|
||||
doc.Delete(dimension.Id);
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
},
|
||||
"拆分尺寸标注"
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user