优化更新代码,添加界面功能并整合
This commit is contained in:
402
ShrlAlgo.RvKits/ModelManager/CorrectReferLevelExecutes.cs
Normal file
402
ShrlAlgo.RvKits/ModelManager/CorrectReferLevelExecutes.cs
Normal file
@@ -0,0 +1,402 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Electrical;
|
||||
using Autodesk.Revit.DB.Mechanical;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
using ShrlAlgo.RvKits.Windows;
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager;
|
||||
|
||||
public class CorrectReferLevelExecutes
|
||||
{
|
||||
public CorrectReferLevelExecutes(UIApplication uiapp)
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
doc = uidoc.Document;
|
||||
view = uidoc.ActiveView;
|
||||
levels =doc.OfClass<Level>()
|
||||
.OfCategory(BuiltInCategory.OST_Levels)
|
||||
.Cast<Level>()
|
||||
.OrderBy(l => l.Elevation)
|
||||
.ToList();
|
||||
levelOutlines = GetRegions(levels);
|
||||
}
|
||||
|
||||
private readonly Document doc;
|
||||
private readonly Dictionary<Level, Outline> levelOutlines;
|
||||
|
||||
private readonly List<Level> levels;
|
||||
|
||||
//private uiApplication uiApplication;
|
||||
private readonly View view;
|
||||
/// <summary>
|
||||
/// 设置族实例
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<MessageModel> SetInstances()
|
||||
{
|
||||
List<MessageModel> errors = [];
|
||||
doc.Invoke(ts =>
|
||||
{
|
||||
//对比标高,得到实际分层位置
|
||||
foreach (var keyPair in levelOutlines)
|
||||
{
|
||||
//得到在标高范围内的元素
|
||||
BoundingBoxIsInsideFilter insideFilter = new(keyPair.Value);
|
||||
var level = keyPair.Key;
|
||||
var insideCollector = new FilteredElementCollector(doc).WherePasses(insideFilter).Where(elem => elem is FamilyInstance && (elem.LevelId != level.Id || elem.get_BoundingBox(view) != null)).ToList();
|
||||
|
||||
foreach (var elem in insideCollector)
|
||||
{
|
||||
try
|
||||
{
|
||||
//获取构件定位方式,基于标高,基于主体(基于面,基于线,基于主体构件:墙板等),基于点
|
||||
if (elem is not FamilyInstance familyInstance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var placementType = familyInstance.Symbol.Family.FamilyPlacementType;
|
||||
|
||||
switch (placementType)
|
||||
{
|
||||
case FamilyPlacementType.OneLevelBased:
|
||||
ModifyOneLevelBasedFamily(doc, level, familyInstance);
|
||||
break;
|
||||
case FamilyPlacementType.OneLevelBasedHosted:
|
||||
break;
|
||||
case FamilyPlacementType.TwoLevelsBased:
|
||||
ModifyTwoLevelBasedFamily(doc, levels, level, familyInstance);
|
||||
break;
|
||||
case FamilyPlacementType.ViewBased:
|
||||
break;
|
||||
case FamilyPlacementType.WorkPlaneBased:
|
||||
ModifyWorkPlaneBasedFamily(doc, level, familyInstance);
|
||||
break;
|
||||
case FamilyPlacementType.CurveBased:
|
||||
ModifyCurveBasedFamily(doc, level, familyInstance);
|
||||
break;
|
||||
case FamilyPlacementType.CurveBasedDetail:
|
||||
break;
|
||||
case FamilyPlacementType.CurveDrivenStructural:
|
||||
break;
|
||||
case FamilyPlacementType.Adaptive:
|
||||
break;
|
||||
case FamilyPlacementType.Invalid:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(new MessageModel(elem, ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "校正族实例标高");
|
||||
return errors;
|
||||
//if (errors.Any())
|
||||
//{
|
||||
// var processorViewModel = new ErrorResolveViewModel(UiDocument, errors);
|
||||
// var errorResolveWin = new ErrorResolveWin(processorViewModel);
|
||||
// WinDialogHelper.ShowAhead(errorResolveWin);
|
||||
//}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置管线
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<MessageModel> SetMEPCurves()
|
||||
{
|
||||
List<MessageModel> errors = [];
|
||||
doc.Invoke(ts =>
|
||||
{
|
||||
//对比标高,得到实际分层位置
|
||||
foreach (var keyPair in levelOutlines)
|
||||
{
|
||||
//得到在标高范围内的元素
|
||||
BoundingBoxIsInsideFilter insideFilter = new(keyPair.Value);
|
||||
var level = keyPair.Key;
|
||||
var insideCollector = new FilteredElementCollector(doc).WherePasses(insideFilter).Where(elem => elem.LevelId != level.Id || elem.get_BoundingBox(view) != null).ToList();
|
||||
|
||||
foreach (var elem in insideCollector)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (elem is Pipe or Duct or CableTray or Conduit)
|
||||
{
|
||||
elem.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM).Set(level.Id);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(new MessageModel(elem, ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "校正管线标高");
|
||||
return errors;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置墙
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<MessageModel> SetWalls()
|
||||
{
|
||||
List<MessageModel> errors = [];
|
||||
doc.Invoke(_ =>
|
||||
{
|
||||
//对比标高,得到实际分层位置
|
||||
foreach (var keyPair in levelOutlines)
|
||||
{
|
||||
//得到在标高范围内的元素
|
||||
BoundingBoxIsInsideFilter insideFilter = new(keyPair.Value);
|
||||
var level = keyPair.Key;
|
||||
var insideCollector = new FilteredElementCollector(doc).WherePasses(insideFilter).Where(elem => elem.LevelId != level.Id || elem.get_BoundingBox(view) != null).ToList();
|
||||
foreach (var elem in insideCollector)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (elem is Wall)
|
||||
{
|
||||
ModifyWall(view, levels, level, elem);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(new MessageModel(elem, ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "校正墙体标高");
|
||||
return errors;
|
||||
//if (errors.Any())
|
||||
//{
|
||||
// var processorViewModel = new ErrorResolveViewModel(UiDocument, errors);
|
||||
// var errorResolveWin = new ErrorResolveWin(processorViewModel);
|
||||
// WinDialogHelper.ShowAhead(errorResolveWin);
|
||||
//}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取基于标高的边界
|
||||
/// </summary>
|
||||
/// <param name="levels"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<Level, Outline> GetRegions(IEnumerable<Level> levels)
|
||||
{
|
||||
Dictionary<Level, Outline> levelOutlines = [];
|
||||
|
||||
////获取标高范围
|
||||
for (var i = 0; i < levels.Count() - 1; i++)
|
||||
{
|
||||
var baseLevel = levels.ElementAt(i);
|
||||
var topLevel = levels.ElementAt(i + 1);
|
||||
XYZ min = new(double.MinValue, double.MinValue, baseLevel.Elevation);
|
||||
XYZ max = new(double.MaxValue, double.MaxValue, topLevel.Elevation);
|
||||
Outline outline = new(min, max);
|
||||
levelOutlines.Add(baseLevel, outline);
|
||||
}
|
||||
|
||||
return levelOutlines;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改基于线的族
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="familyInstance"></param>
|
||||
private static void ModifyCurveBasedFamily(Document doc, Level level, FamilyInstance familyInstance)
|
||||
{
|
||||
var originOffset = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).AsDouble();
|
||||
if (familyInstance.Host is not Level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!familyInstance.Symbol.IsActive)
|
||||
{
|
||||
familyInstance.Symbol.Activate();
|
||||
}
|
||||
|
||||
var hostLevel = familyInstance.Host as Level;
|
||||
var offset = hostLevel.Elevation + originOffset - level.Elevation;
|
||||
var loc = familyInstance.Location as LocationCurve;
|
||||
var p1 = loc.Curve.GetEndPoint(0);
|
||||
var p2 = loc.Curve.GetEndPoint(1);
|
||||
var line = Line.CreateBound(p1.Add(XYZ.BasisZ * level.Elevation), p2.Add(XYZ.BasisZ * level.Elevation));
|
||||
|
||||
var newFamilyInstance = doc.Create.NewFamilyInstance(level.GetPlaneReference(), line, familyInstance.Symbol);
|
||||
var offsetParam = newFamilyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
|
||||
offsetParam.Set(offset);
|
||||
foreach (Parameter param in familyInstance.Parameters)
|
||||
{
|
||||
if (param.IsReadOnly || param.Definition.Name == offsetParam.Definition.Name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (param.StorageType)
|
||||
{
|
||||
case StorageType.None:
|
||||
break;
|
||||
case StorageType.Integer:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsInteger());
|
||||
break;
|
||||
case StorageType.Double:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsDouble());
|
||||
break;
|
||||
case StorageType.String:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsString());
|
||||
break;
|
||||
case StorageType.ElementId:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsElementId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
doc.Delete(familyInstance.Id);
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改基于标高的族
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="familyInstance"></param>
|
||||
private static void ModifyOneLevelBasedFamily(Document doc, Level level, FamilyInstance familyInstance)
|
||||
{
|
||||
var baseLevelParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM);
|
||||
var originLevel = doc.GetElement(baseLevelParam.AsElementId()) as Level;
|
||||
baseLevelParam.Set(level.Id);
|
||||
|
||||
var param = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
|
||||
if (param == null || param.IsReadOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var value = param.AsDouble();
|
||||
param.Set(originLevel.Elevation + value - level.Elevation);
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改基于两个标高的族
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="levels"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="familyInstance"></param>
|
||||
private static void ModifyTwoLevelBasedFamily(Document doc, List<Level> levels, Level level, FamilyInstance familyInstance)
|
||||
{
|
||||
var n = levels.FindIndex(l => l.Id == level.Id);
|
||||
|
||||
var baseLevelParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM);
|
||||
var originLevel = doc.GetElement(baseLevelParam.AsElementId()) as Level;
|
||||
baseLevelParam.Set(level.Id);
|
||||
|
||||
var baseOffsetParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM);
|
||||
|
||||
var baseOffsetValue = baseOffsetParam.AsDouble();
|
||||
baseOffsetParam.Set(baseOffsetValue + originLevel.Elevation - level.Elevation);
|
||||
|
||||
var topLevelParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);
|
||||
originLevel = doc.GetElement(topLevelParam.AsElementId()) as Level;
|
||||
topLevelParam.Set(levels[n + 1].Id);
|
||||
|
||||
var topOffsetParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM);
|
||||
|
||||
var topOffsetValue = topOffsetParam.AsDouble();
|
||||
|
||||
familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(originLevel.Elevation + topOffsetValue - levels[n + 1].Elevation);
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改基于墙
|
||||
/// </summary>
|
||||
/// <param name="view"></param>
|
||||
/// <param name="levels"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="elem"></param>
|
||||
private static void ModifyWall(View view, List<Level> levels, Level level, Element elem)
|
||||
{
|
||||
var wall = (Wall)elem;
|
||||
var doc = elem.Document;
|
||||
var isExist = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).Cast<FamilyInstance>().Any(fi => fi.Host?.Id == wall.Id);
|
||||
if (isExist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var n = levels.FindIndex(l => l.Id == level.Id);
|
||||
var wallBox = wall.get_BoundingBox(view);
|
||||
var minZ = wallBox.Min.Z;
|
||||
var maxZ = wallBox.Max.Z;
|
||||
|
||||
wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).Set(level.Id);
|
||||
wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(minZ - level.Elevation);
|
||||
wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(levels[n + 1].Id);
|
||||
wall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(maxZ - levels[n + 1].Elevation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改基于工作平面的族
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="familyInstance"></param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
private static void ModifyWorkPlaneBasedFamily(Document doc, Level level, FamilyInstance familyInstance)
|
||||
{
|
||||
var baseLevelParam = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
|
||||
|
||||
//var originLevel = doc.GetElement(baseLevelParam.AsElementId()) as Level;
|
||||
//var hostParam = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_PARAM);
|
||||
//var hostParamValue = doc.GetElement(hostParam.AsElementId());
|
||||
|
||||
if (familyInstance.Host is Level)
|
||||
{
|
||||
if (!familyInstance.Symbol.IsActive)
|
||||
{
|
||||
familyInstance.Symbol.Activate();
|
||||
}
|
||||
|
||||
var lop = familyInstance.Location as LocationPoint;
|
||||
var newFamilyInstance = doc.Create.NewFamilyInstance(level.GetPlaneReference(), lop?.Point, familyInstance.HandOrientation, familyInstance.Symbol);
|
||||
var p = newFamilyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).Definition;
|
||||
foreach (Parameter param in familyInstance.Parameters)
|
||||
{
|
||||
if (param.IsReadOnly || param.Definition.Name == p.Name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (param.StorageType)
|
||||
{
|
||||
case StorageType.None:
|
||||
break;
|
||||
case StorageType.Integer:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsInteger());
|
||||
break;
|
||||
case StorageType.Double:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsDouble());
|
||||
break;
|
||||
case StorageType.String:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsString());
|
||||
break;
|
||||
case StorageType.ElementId:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsElementId());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
doc.Delete(familyInstance.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (baseLevelParam.IsReadOnly == false)
|
||||
{
|
||||
baseLevelParam.Set(level.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
ShrlAlgo.RvKits/ModelManager/ModelCheckCmd.cs
Normal file
12
ShrlAlgo.RvKits/ModelManager/ModelCheckCmd.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager;
|
||||
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
[Regeneration(RegenerationOption.Manual)]
|
||||
public class ModelCheckCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute() => SingletonChildWindowManager.ShowOrActivate<ModelCheckView, ModelCheckViewModel>(UiApplication);//ModelCheckView view = SingletonViewHelper<ModelCheckView>.GetInstance(out var isNewCreate);//if (isNewCreate)//{// view.DataContext = new ModelCheckViewModel(uiApplication);// view.ShowAhead();//}//view.Activate();
|
||||
}
|
||||
168
ShrlAlgo.RvKits/ModelManager/ModelCheckView.xaml
Normal file
168
ShrlAlgo.RvKits/ModelManager/ModelCheckView.xaml
Normal file
@@ -0,0 +1,168 @@
|
||||
<wpf:FluentWindowEx
|
||||
x:Class="ShrlAlgo.RvKits.ModelManager.ModelCheckView"
|
||||
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:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ShrlAlgo.RvKits.RvFamily"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:wpf="https://github.com/ShrlAlgo/WPFluent"
|
||||
xmlns:modelManager="clr-namespace:ShrlAlgo.RvKits.ModelManager"
|
||||
Title="模型检查"
|
||||
Width="600"
|
||||
MinHeight="500"
|
||||
d:DataContext="{d:DesignInstance modelManager:ModelCheckViewModel}"
|
||||
wpf:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
|
||||
wpf:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
mc:Ignorable="d">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/ShrlAlgo.RvKits;component/WPFUI.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type GroupItem}">
|
||||
<Expander Header="{Binding Name}" IsExpanded="True">
|
||||
<!--<Expander.Header>
|
||||
<TextBlock Text="{Binding Path=Name}"/>
|
||||
</Expander.Header>-->
|
||||
<ItemsPresenter />
|
||||
</Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</Window.Resources>
|
||||
<wpf:AutoGridEx
|
||||
ChildMargin="5"
|
||||
Columns="*,Auto"
|
||||
Rows="*,Auto,Auto">
|
||||
<DataGrid
|
||||
Grid.ColumnSpan="2"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
IsReadOnly="True"
|
||||
ItemsSource="{Binding Items}"
|
||||
ToolTip="双击行可快速定位">
|
||||
<b:Interaction.Triggers>
|
||||
<b:EventTrigger EventName="MouseDoubleClick">
|
||||
<b:InvokeCommandAction Command="{Binding ShowElementCommand}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}, Mode=FindAncestor}}" />
|
||||
</b:EventTrigger>
|
||||
</b:Interaction.Triggers>
|
||||
<DataGrid.GroupStyle>
|
||||
<GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
|
||||
<GroupStyle.Panel>
|
||||
<ItemsPanelTemplate>
|
||||
<DataGridRowsPresenter />
|
||||
</ItemsPanelTemplate>
|
||||
</GroupStyle.Panel>
|
||||
</GroupStyle>
|
||||
</DataGrid.GroupStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding Element.Id}" Header="ID" />
|
||||
<DataGridTextColumn Binding="{Binding Element.Category.Name}" Header="族类别名称" />
|
||||
<DataGridTextColumn Binding="{Binding Element.Name}" Header="类型或实例名称" />
|
||||
<!--<DataGridTextColumn Binding="{Binding ErrorMessage}" Header="错误信息" />-->
|
||||
<!--<DataGridTemplateColumn Header="操作">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
-->
|
||||
<!-- 按钮参数绑定到当前行的绑定的Item -->
|
||||
<!--
|
||||
<Button
|
||||
Command="{Binding DataContext.ShowElementCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"
|
||||
CommandParameter="{Binding}"
|
||||
Content="定位构件" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>-->
|
||||
<!-- ReSharper disable once Xaml.BindingWithContextNotResolved -->
|
||||
<DataGridTextColumn Binding="{Binding Element.ReferenceLevel.Name}" Header="参照标高" />
|
||||
<!-- ReSharper disable once Xaml.BindingWithContextNotResolved -->
|
||||
<DataGridTextColumn Binding="{Binding Element.MEPSystem.Name}" Header="系统" />
|
||||
<!-- ReSharper disable once Xaml.BindingWithContextNotResolved -->
|
||||
<DataGridTextColumn Binding="{Binding Element.Host.Name}" Header="主体" />
|
||||
<!-- ReSharper disable once Xaml.BindingWithContextNotResolved -->
|
||||
<DataGridTextColumn Binding="{Binding Element.Room.Name}" Header="房间" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2">
|
||||
<wpf:Card>
|
||||
<TextBlock Text="{Binding ProjectBasePoint, StringFormat=项目基点:{}{0}}" />
|
||||
</wpf:Card>
|
||||
<wpf:Card>
|
||||
<TextBlock Text="{Binding SharedBasePoint, StringFormat=测量点:{}{0}}" />
|
||||
</wpf:Card>
|
||||
</StackPanel>
|
||||
<UniformGrid
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Rows="3">
|
||||
<CheckBox
|
||||
Content="管线坡度"
|
||||
IsChecked="{Binding IsCheckSlope}"
|
||||
ToolTip="管线坡度错误" />
|
||||
<CheckBox
|
||||
Content="孤立管线"
|
||||
IsChecked="{Binding IsCheckLength}"
|
||||
ToolTip="检查管线长度是否过短" />
|
||||
<CheckBox
|
||||
Content="参照标高"
|
||||
IsChecked="{Binding IsCheckLevel}"
|
||||
ToolTip="检查构件的参照标高" />
|
||||
<CheckBox
|
||||
Content="命名要求"
|
||||
IsChecked="{Binding IsCheckName}"
|
||||
ToolTip="检查构件的三段式命名" />
|
||||
<CheckBox
|
||||
Content="构件复杂度"
|
||||
IsChecked="{Binding IsCheckSymbolGeometry}"
|
||||
ToolTip="检查构件的复杂程度,避免模型导出、轻量化失败" />
|
||||
<CheckBox
|
||||
Content="属性检查"
|
||||
IsChecked="{Binding IsCheckProps}"
|
||||
ToolTip="检查构件属性是否存在,是否填写" />
|
||||
<CheckBox
|
||||
Content="重叠管线"
|
||||
IsChecked="{Binding IsCheckEqual}"
|
||||
ToolTip="检查管线是否重叠" />
|
||||
</UniformGrid>
|
||||
<UniformGrid
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Rows="2">
|
||||
<UniformGrid Rows="2">
|
||||
<TextBlock Text="{Binding ErrorCount, Mode=TwoWay, StringFormat=错误数量:{}{0}}" TextWrapping="WrapWithOverflow" />
|
||||
<CheckBox Content="使用剖切框" IsChecked="{Binding UseSectionBox}" />
|
||||
</UniformGrid>
|
||||
<UniformGrid Rows="2">
|
||||
<!--
|
||||
md:ButtonProgressAssist.IsIndeterminate="{Binding CheckModelCommand.ExecutionTask,Converter={StaticResource TaskResultConverter}, Mode=OneWay}"
|
||||
md:ButtonProgressAssist.IsIndicatorVisible="{Binding CheckModelCommand.IsRunning, Converter={StaticResource BooleanToVisibilityConverter}, Mode=OneWay}"
|
||||
md:ButtonProgressAssist.Value="-1"
|
||||
-->
|
||||
<Button
|
||||
Width="80"
|
||||
Margin="5"
|
||||
Command="{Binding CheckModelCommand}"
|
||||
Content="模型检查" />
|
||||
<Button
|
||||
Width="80"
|
||||
Command="{Binding ExportToExcelCommand}"
|
||||
Content="导出结果" />
|
||||
<Button
|
||||
Width="80"
|
||||
Margin="5"
|
||||
Command="{Binding ModifyModelCommand}"
|
||||
Content="矫正错误"
|
||||
ToolTip="对参照标高进行修改、立管坡度修正" />
|
||||
</UniformGrid>
|
||||
</UniformGrid>
|
||||
</wpf:AutoGridEx>
|
||||
</wpf:FluentWindowEx>
|
||||
13
ShrlAlgo.RvKits/ModelManager/ModelCheckView.xaml.cs
Normal file
13
ShrlAlgo.RvKits/ModelManager/ModelCheckView.xaml.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace ShrlAlgo.RvKits.ModelManager
|
||||
{
|
||||
/// <summary>
|
||||
/// ModelCheckView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ModelCheckView
|
||||
{
|
||||
public ModelCheckView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
668
ShrlAlgo.RvKits/ModelManager/ModelCheckViewModel.cs
Normal file
668
ShrlAlgo.RvKits/ModelManager/ModelCheckViewModel.cs
Normal file
@@ -0,0 +1,668 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Data;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Architecture;
|
||||
using Autodesk.Revit.DB.Electrical;
|
||||
using Autodesk.Revit.DB.Mechanical;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
using Autodesk.Revit.UI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Win32;
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
|
||||
using ShrlAlgo.RvKits.Windows;
|
||||
|
||||
// ReSharper disable PossibleMultipleEnumeration
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager;
|
||||
|
||||
public partial class ModelCheckViewModel : ObservableObject
|
||||
{
|
||||
private readonly CorrectReferLevelExecutes correctReferLevelExecutes;
|
||||
|
||||
private readonly ActionEventHandler modifyModel = new();
|
||||
private readonly ActionEventHandler showElementsSectionBox = new();
|
||||
private readonly UIApplication uiapp;
|
||||
|
||||
public ModelCheckViewModel(UIApplication uiapp)
|
||||
{
|
||||
Items = [];
|
||||
var cv = CollectionViewSource.GetDefaultView(Items);
|
||||
cv.GroupDescriptions.Add(new PropertyGroupDescription("ErrorMessage"));
|
||||
correctReferLevelExecutes = new CorrectReferLevelExecutes(uiapp);
|
||||
this.uiapp = uiapp;
|
||||
FindBasePoint();
|
||||
}
|
||||
|
||||
private bool CanExport()
|
||||
{
|
||||
return Items.Any();
|
||||
}
|
||||
private static bool CanShowElement(object obj)
|
||||
{
|
||||
return obj is MessageModel { IsInstance: true };
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private /*async Task*/ void CheckModel(/*CancellationToken token*/)
|
||||
{
|
||||
//if (Items.Any())
|
||||
//{
|
||||
// Items = [];
|
||||
//}
|
||||
Items.Clear();
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
//await Task.Delay(TimeSpan.FromSeconds(2), token);
|
||||
//if (doc.ActiveView is not View3D view3d)
|
||||
//{
|
||||
// view3d = doc.OfClass<View3D>().FirstOrDefault(e => FilteredElementCollector.IsViewValidForElementIteration(doc, e.Id)) as View3D;
|
||||
//}
|
||||
var elements = doc.OfParentModelElements();
|
||||
var typeInstancesGroups = elements.GroupBy(e => e.GetTypeId());
|
||||
if (IsCheckLevel)
|
||||
{
|
||||
var levels = doc.OfClass<Level>().OfType<Level>().OrderBy(l => l.Elevation);
|
||||
var levelOutlines = CorrectReferLevelExecutes.GetRegions(levels);
|
||||
foreach (var keyPair in levelOutlines)
|
||||
{
|
||||
//得到在标高范围内的元素
|
||||
BoundingBoxIsInsideFilter insideFilter = new(keyPair.Value);
|
||||
var level = keyPair.Key;
|
||||
var insideCollector = new FilteredElementCollector(doc)
|
||||
.WherePasses(insideFilter)
|
||||
.Where(elem => elem.get_BoundingBox(doc.ActiveView) != null)
|
||||
.ToList();
|
||||
foreach (var elem in insideCollector)
|
||||
{
|
||||
var isCorrect = false;
|
||||
var hasReferenceLevel = false;
|
||||
foreach (Parameter param in elem.Parameters)
|
||||
{
|
||||
if (param.Definition.Name.Contains("标高") || param.Definition.Name.Contains("Level"))
|
||||
{
|
||||
hasReferenceLevel = param.StorageType == StorageType.ElementId;
|
||||
if (hasReferenceLevel)
|
||||
{
|
||||
var value = param.AsElementId();
|
||||
isCorrect = value == ElementId.InvalidElementId || param.AsElementId() == level.Id; //扶手等对象有宿主Host时为空
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasReferenceLevel && !isCorrect)
|
||||
{
|
||||
Items.Add(new MessageModel(elem, "参照标高有误"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsCheckName)
|
||||
{
|
||||
foreach (var item in typeInstancesGroups)
|
||||
{
|
||||
var id = item.Key;
|
||||
var type = doc.GetElement(id);
|
||||
var array = type.Name.Split('-');
|
||||
if (array.Length >= 3)
|
||||
{
|
||||
var prefix = array[0].Trim();
|
||||
if (
|
||||
prefix
|
||||
is not (
|
||||
"QQ"
|
||||
or "YT"
|
||||
or "XL"
|
||||
or "GJ"
|
||||
or "CL"
|
||||
or "JZ"
|
||||
or "JG"
|
||||
or "GP"
|
||||
or "DZ"
|
||||
or "TF"
|
||||
or "GD"
|
||||
or "TX"
|
||||
or "XH"
|
||||
or "ZS"
|
||||
or "HB"
|
||||
or "ZJ"
|
||||
or "HJ"
|
||||
or "CX"
|
||||
or "MJ"
|
||||
or "YK"
|
||||
or "ZK"
|
||||
or "ZT"
|
||||
or "CJ"
|
||||
or "XX"
|
||||
or "TC"
|
||||
or "NY"
|
||||
or "ZB"
|
||||
or "AF"
|
||||
)
|
||||
)
|
||||
{
|
||||
var errorItem = new MessageModel(type, "类型专业前缀错误");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorItem = new MessageModel(type, "类型名称不符合三段式");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
}
|
||||
//var familyGroups = doc.OfClass<FamilyInstance>().ToElements().Cast<FamilyInstance>().GroupBy(instance => instance.Symbol.Family);
|
||||
//foreach (var group in familyGroups)
|
||||
//{
|
||||
// var array = group.Key.Name.Split('-');
|
||||
// if (array.Length >= 3)
|
||||
// {
|
||||
// var prefix = array[0].Trim();
|
||||
// if (prefix is not ("QQ" or "YT" or "XL" or "GJ" or "CL" or "JZ" or "JG" or "GP" or "DZ" or "TF" or "GD" or "TX" or "XH" or "ZS" or "HB" or "ZJ" or "HJ" or "CX" or "MJ" or "YK" or "ZK" or "ZT" or "CJ" or "XX" or "TC" or "NY" or "ZB" or "AF"))
|
||||
// {
|
||||
// var errorItem = new MessageModel(group.Key, "族名称专业前缀错误");
|
||||
// Items.Add(errorItem);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var errorItem = new MessageModel(group.Key, "族名称命名不符合三段式");
|
||||
// Items.Add(errorItem);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
if (IsCheckProps)
|
||||
{
|
||||
foreach (var group in typeInstancesGroups)
|
||||
{
|
||||
var typeCount = 0;
|
||||
var typeId = group.Key;
|
||||
var type = doc.GetElement(typeId);
|
||||
foreach (Parameter param in type.Parameters)
|
||||
{
|
||||
var array = param.Definition.Name.Split('-');
|
||||
if (array.Length >= 3)
|
||||
{
|
||||
var prefix = array[0].Trim();
|
||||
if (prefix is ("ID" or "LC" or "ST" or "GJ" or "MF" or "AM" or "FM" or "TM" or "CM"))
|
||||
{
|
||||
typeCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var elem in group)
|
||||
{
|
||||
var instanceCount = 0;
|
||||
foreach (Parameter param in elem.Parameters)
|
||||
{
|
||||
var array = param.Definition.Name.Split('-');
|
||||
if (array.Length >= 3)
|
||||
{
|
||||
var prefix = array[0].Trim();
|
||||
if (prefix is ("ID" or "LC" or "ST" or "GJ" or "MF" or "AM" or "FM" or "TM" or "CM"))
|
||||
{
|
||||
instanceCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeCount + instanceCount < 60)
|
||||
{
|
||||
var errorItem = new MessageModel(elem, "规范参数不全");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsCheckSlope)
|
||||
{
|
||||
var mepCurves = doc.OfClass<MEPCurve>().Where(e => e is not InsulationLiningBase and not FlexDuct and not FlexPipe);
|
||||
foreach (var mepCurve in mepCurves)
|
||||
{
|
||||
var isError = false;
|
||||
if (mepCurve is Pipe)
|
||||
{
|
||||
var param = mepCurve.get_Parameter(BuiltInParameter.RBS_PIPE_SLOPE);
|
||||
isError = param.HasValue && ((param.AsDouble() < 0.25 && param.AsDouble() > 10E-6) || param.AsDouble() > Math.PI); //坡度过大或过小时,90度时AsDouble为0
|
||||
}
|
||||
else if (mepCurve is Duct)
|
||||
{
|
||||
var param = mepCurve.get_Parameter(BuiltInParameter.RBS_DUCT_SLOPE);
|
||||
isError = param.HasValue && ((param.AsDouble() < 0.25 && param.AsDouble() > 10E-6) || param.AsDouble() > Math.PI); //坡度过大或过小时,90度时AsDouble为0
|
||||
}
|
||||
else if (mepCurve is Conduit or CableTray)
|
||||
{
|
||||
var p1 = mepCurve.get_Parameter(BuiltInParameter.RBS_START_OFFSET_PARAM).AsDouble();
|
||||
var p2 = mepCurve.get_Parameter(BuiltInParameter.RBS_END_OFFSET_PARAM).AsDouble();
|
||||
var l = mepCurve.get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH).AsDouble();
|
||||
var sin = Math.Abs(p1 - p2) / l;
|
||||
var radian = Math.Asin(sin);
|
||||
var slope = Math.Tan(radian);
|
||||
isError = slope is (> 10E-6 and < 0.25) || (slope > Math.PI && Math.Abs(radian - Math.PI / 2) > 10E-6);
|
||||
}
|
||||
|
||||
if (isError)
|
||||
{
|
||||
var errorItem = new MessageModel(mepCurve, "管线坡度有误差");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsCheckLength)
|
||||
{
|
||||
var mepCurves = doc.OfClass<MEPCurve>().Where(e => e is not InsulationLiningBase);
|
||||
foreach (var mepCurve in mepCurves)
|
||||
{
|
||||
var length = mepCurve.get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH).AsDouble();
|
||||
var connectors = mepCurve.GetConnectors(true);
|
||||
if (length < 500 / 304.8 && connectors.Size == 2)
|
||||
{
|
||||
var errorItem = new MessageModel(mepCurve, "管道孤立或长度有误");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsCheckEqual)
|
||||
{
|
||||
var mepCurves = doc.OfClass<MEPCurve>().Where(e => e is not InsulationLiningBase).ToList();
|
||||
foreach (var c1 in mepCurves)
|
||||
{
|
||||
foreach (var c2 in mepCurves)
|
||||
{
|
||||
if (c1.Id != c2.Id)
|
||||
{
|
||||
var result = c1.GetCurve().Intersect(c2.GetCurve());
|
||||
if (result == SetComparisonResult.Equal)
|
||||
{
|
||||
var errorItem = new MessageModel(c1, "管线存在重叠");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsCheckSymbolGeometry)
|
||||
{
|
||||
foreach (var grouping in typeInstancesGroups)
|
||||
{
|
||||
var symbolId = grouping.Key;
|
||||
|
||||
if (doc.GetElement(symbolId) is not FamilySymbol symbol)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
symbol.get_Geometry(new Options());
|
||||
Options option = new() { ComputeReferences = true, DetailLevel = ViewDetailLevel.Fine };
|
||||
var geometryElement = symbol.get_Geometry(option);
|
||||
if (geometryElement == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var count = 0;
|
||||
foreach (var geomObj in geometryElement)
|
||||
{
|
||||
if (geomObj is GeometryInstance geomInstance)
|
||||
{
|
||||
#if REVIT2018 || REVIT2020
|
||||
if (geomInstance.Symbol is CADLinkType)
|
||||
{
|
||||
var errorItem = new MessageModel(symbol, "构件类型包含dwg模型");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
#elif REVIT2025
|
||||
if (doc.GetElement(geomInstance.GetSymbolGeometryId().SymbolId) is CADLinkType)
|
||||
{
|
||||
var errorItem = new MessageModel(symbol, "构件类型包含dwg模型");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
if (geomObj is Solid)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 50)
|
||||
{
|
||||
var errorItem = new MessageModel(symbol, "构件类型几何需考虑简化(超过50个实体)");
|
||||
Items.Add(errorItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
ErrorCount = Items.Count;
|
||||
ExportToExcelCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanExport))]
|
||||
private void ExportToExcel()
|
||||
{
|
||||
var fileName = uiapp.ActiveUIDocument.Document.Title;
|
||||
var dialog = new SaveFileDialog()
|
||||
{
|
||||
Title = "导出结果",
|
||||
AddExtension = true,
|
||||
DefaultExt = ".xlsx",
|
||||
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),
|
||||
Filter = "Excel表格(*.xlsx)|*.xlsx",
|
||||
OverwritePrompt = true,
|
||||
FileName = $"{fileName.Substring(0, fileName.Length - 4)}_检查结果"
|
||||
};
|
||||
if (dialog.ShowDialog() != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||||
|
||||
try
|
||||
{
|
||||
EPPlusHelper.WriteExcel(
|
||||
dialog.FileName,
|
||||
m =>
|
||||
{
|
||||
var groups = Items.GroupBy(e => e.ErrorMessage);
|
||||
foreach (var group in groups)
|
||||
{
|
||||
var sheet = m.Workbook.Worksheets.Add(group.Key);
|
||||
//int columns = tdd.NumberOfColumns;
|
||||
//int rows = group.Count() + 1;
|
||||
for (var i = -1; i < group.Count(); i++)
|
||||
{
|
||||
if (i == -1)
|
||||
{
|
||||
sheet.Cells[1, 1].Value = "元素ID";
|
||||
sheet.Cells[1, 2].Value = "族类别";
|
||||
sheet.Cells[1, 3].Value = "类型或实例名称";
|
||||
sheet.Cells[1, 4].Value = "参照标高";
|
||||
sheet.Cells[1, 5].Value = "系统";
|
||||
sheet.Cells[1, 6].Value = "主体";
|
||||
sheet.Cells[1, 7].Value = "房间";
|
||||
}
|
||||
else
|
||||
{
|
||||
var elem = group.ElementAt(i).Element;
|
||||
|
||||
var type = elem.GetType();
|
||||
var host = type.GetProperty("Host");
|
||||
var level = type.GetProperty("ReferenceLevel");
|
||||
var mepSystem = type.GetProperty("MEPSystem");
|
||||
var room = type.GetProperty("Room");
|
||||
sheet.Cells[i + 2, 1].Value = elem.Id.ToString();
|
||||
sheet.Cells[i + 2, 2].Value = elem.Category.Name;
|
||||
sheet.Cells[i + 2, 3].Value = elem.Name;
|
||||
|
||||
if (level != null)
|
||||
{
|
||||
sheet.Cells[i + 2, 4].Value = (level.GetValue(elem, null) as Level)?.Name;
|
||||
}
|
||||
if (mepSystem != null)
|
||||
{
|
||||
sheet.Cells[i + 2, 5].Value = (mepSystem.GetValue(elem, null) as MEPSystem)?.Name;
|
||||
}
|
||||
if (host != null)
|
||||
{
|
||||
sheet.Cells[i + 2, 6].Value = (host.GetValue(elem, null) as Element)?.Name;
|
||||
}
|
||||
if (room != null)
|
||||
{
|
||||
sheet.Cells[i + 2, 7].Value = (room.GetValue(room, null) as Room)?.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
EPPlusHelper.SetTitle(sheet, 1, 1, 1, 7);
|
||||
EPPlusHelper.SetStyle(sheet, 2, 1, group.Count() + 1, 7);
|
||||
|
||||
var range = sheet.Cells[1, 1, group.Count() + 1, 7];
|
||||
range.AutoFitColumns();
|
||||
}
|
||||
}
|
||||
);
|
||||
WinDialogHelper.OpenFolderAndSelectFile(dialog.FileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.ToLog(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void FindBasePoint()
|
||||
{
|
||||
var basePoints = uiapp.ActiveUIDocument.Document.OfClass<BasePoint>().OfType<BasePoint>();
|
||||
foreach (var item in basePoints)
|
||||
{
|
||||
//南北
|
||||
var ns = Math.Round(
|
||||
item.get_Parameter(BuiltInParameter.BASEPOINT_NORTHSOUTH_PARAM).AsDouble() * 0.3048,
|
||||
4,
|
||||
MidpointRounding.AwayFromZero
|
||||
);
|
||||
//东西
|
||||
var ew = Math.Round(item.get_Parameter(BuiltInParameter.BASEPOINT_EASTWEST_PARAM).AsDouble() * 0.3048, 4, MidpointRounding.AwayFromZero);
|
||||
//高程
|
||||
var elev = Math.Round(
|
||||
item.get_Parameter(BuiltInParameter.BASEPOINT_ELEVATION_PARAM).AsDouble() * 0.3048,
|
||||
4,
|
||||
MidpointRounding.AwayFromZero
|
||||
);
|
||||
if (item.IsShared)//测量点
|
||||
{
|
||||
SharedBasePoint = $"南北:{ns}m;东西:{ew}m;高程:{elev}m";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.Category.GetHashCode() == -2001271)//项目基点
|
||||
{
|
||||
//正北角度
|
||||
var angle = item.get_Parameter(BuiltInParameter.BASEPOINT_ANGLETON_PARAM).AsValueString();
|
||||
ProjectBasePoint = $"南北:{ns}m;东西:{ew}m;高程:{elev}m;角度:{angle}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void ModifyModel()
|
||||
{
|
||||
var errorItems = new List<MessageModel>();
|
||||
modifyModel.Raise(_ =>
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
doc.Invoke(
|
||||
_ =>
|
||||
{
|
||||
#region 参照标高
|
||||
var errorItems1 = correctReferLevelExecutes.SetWalls();
|
||||
errorItems.AddRange(errorItems1);
|
||||
var errorItems2 = correctReferLevelExecutes.SetInstances();
|
||||
errorItems.AddRange(errorItems2);
|
||||
var errorItems3 = correctReferLevelExecutes.SetMEPCurves();
|
||||
errorItems.AddRange(errorItems3);
|
||||
#endregion
|
||||
#region 立管坡度修正
|
||||
foreach (var error in Items)
|
||||
{
|
||||
if (error.ErrorMessage != "管线坡度有误差")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var elem = error.Element;
|
||||
if (elem is MEPCurve mep)
|
||||
{
|
||||
var loc = mep.Location as LocationCurve;
|
||||
var line = loc!.Curve as Line;
|
||||
var endPoint = line!.GetEndPoint(0);
|
||||
var endPoint1 = line.GetEndPoint(1);
|
||||
Line unboundLine;
|
||||
Line l;
|
||||
var xoy1 = endPoint.Flatten();
|
||||
var xoy2 = endPoint1.Flatten();
|
||||
var tan = Math.Abs(endPoint.Z - endPoint1.Z) / xoy1.DistanceTo(xoy2);
|
||||
var dir = -XYZ.BasisZ;
|
||||
|
||||
if (endPoint.Z > endPoint1.Z) //以高点作为基准,修改低点
|
||||
{
|
||||
if (tan > 1)
|
||||
{
|
||||
unboundLine = Line.CreateUnbound(endPoint, dir);
|
||||
var startPoint = unboundLine.Project(endPoint1).XYZPoint;
|
||||
l = Line.CreateBound(endPoint, startPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = xoy2 - xoy1;
|
||||
unboundLine = Line.CreateUnbound(endPoint, dir);
|
||||
var startPoint = unboundLine.Project(endPoint1).XYZPoint;
|
||||
l = Line.CreateBound(endPoint, startPoint);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tan > 1)
|
||||
{
|
||||
unboundLine = Line.CreateUnbound(endPoint1, dir);
|
||||
var startPoint = unboundLine.Project(endPoint).XYZPoint;
|
||||
l = Line.CreateBound(startPoint, endPoint1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = xoy2 - xoy1;
|
||||
unboundLine = Line.CreateUnbound(endPoint1, dir);
|
||||
var startPoint = unboundLine.Project(endPoint).XYZPoint;
|
||||
l = Line.CreateBound(startPoint, endPoint1);
|
||||
}
|
||||
}
|
||||
|
||||
loc.Curve = l;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
},
|
||||
"模型调整"
|
||||
);
|
||||
if (errorItems.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SingletonChildWindowManager.ShowOrActivate<MessageWin, MessageViewModel>(uiapp.ActiveUIDocument, errorItems, "未解决错误");
|
||||
});
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanShowElement))]
|
||||
private void ShowElement(object obj)
|
||||
{
|
||||
if (obj is MessageModel model)
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
//if (UiDocument.ActiveView.IsTemporaryHideIsolateActive())
|
||||
//{
|
||||
// UiDocument.ActiveView.temporary
|
||||
//}
|
||||
if (model.Element.IsValidObject)
|
||||
{
|
||||
if (model.Element.IsHidden(uidoc.ActiveView))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<ElementId> ids = [model.Element.Id];
|
||||
//UiDocument.ActiveView.IsolateElementTemporary(model.ElementToMove.ViewId);
|
||||
showElementsSectionBox.Raise(_ =>
|
||||
{
|
||||
if (uidoc.ActiveView is not View3D view3d)
|
||||
{
|
||||
view3d =
|
||||
doc.OfClass<View3D>().FirstOrDefault(e => FilteredElementCollector.IsViewValidForElementIteration(doc, e.Id)) as View3D;
|
||||
}
|
||||
uidoc.ActiveView = view3d;
|
||||
|
||||
doc.Invoke(_ =>
|
||||
{
|
||||
if (UseSectionBox)
|
||||
{
|
||||
doc.InvokeSub(_ => view3d.SectionBoxElements(ids));
|
||||
}
|
||||
view3d.ZoomElements(uidoc, ids);
|
||||
uidoc.Selection.SetElementIds(ids);
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Items.Remove(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int ErrorCount { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsCheckEqual { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsCheckLength { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsCheckLevel { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsCheckName { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsCheckProps { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsCheckSlope { get; set; }
|
||||
[ObservableProperty]
|
||||
public partial bool IsCheckSymbolGeometry { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<MessageModel> Items { get; set; }
|
||||
[ObservableProperty]
|
||||
public partial int MyProperty { get; set; }
|
||||
|
||||
public string ProjectBasePoint { get; set; }
|
||||
|
||||
public string SharedBasePoint { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool UseSectionBox { get; set; }
|
||||
}
|
||||
|
||||
public enum ModelCheckType
|
||||
{
|
||||
/// <summary>
|
||||
/// 命名
|
||||
/// </summary>
|
||||
Name,
|
||||
|
||||
/// <summary>
|
||||
/// 坡度问题
|
||||
/// </summary>
|
||||
Slope,
|
||||
|
||||
/// <summary>
|
||||
/// 参照标高
|
||||
/// </summary>
|
||||
ReferenceLevel,
|
||||
|
||||
/// <summary>
|
||||
/// 属性检查
|
||||
/// </summary>
|
||||
Property,
|
||||
|
||||
/// <summary>
|
||||
/// 管线重叠
|
||||
/// </summary>
|
||||
Equal,
|
||||
|
||||
/// <summary>
|
||||
/// 管线过短,或孤立管线
|
||||
/// </summary>
|
||||
Length
|
||||
}
|
||||
18
ShrlAlgo.RvKits/ModelManager/SeparateModelCmd.cs
Normal file
18
ShrlAlgo.RvKits/ModelManager/SeparateModelCmd.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager;
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
[Regeneration(RegenerationOption.Manual)]
|
||||
public class SeparateModelCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
//var win = new SeparateModelWin();
|
||||
//win.Show();
|
||||
SingletonChildWindowManager.ShowOrActivate<SeparateModelWin, SeparateModelViewModel>();
|
||||
}
|
||||
}
|
||||
80
ShrlAlgo.RvKits/ModelManager/SeparateModelViewModel.cs
Normal file
80
ShrlAlgo.RvKits/ModelManager/SeparateModelViewModel.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
using UIFrameworkServices;
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager
|
||||
{
|
||||
public partial class SeparateModelViewModel : ObservableObject
|
||||
{
|
||||
private readonly ActionEventHandler separate = new();
|
||||
|
||||
[ObservableProperty]
|
||||
private string fileName = "示例";
|
||||
[ObservableProperty]
|
||||
private string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||
|
||||
[RelayCommand]
|
||||
private void Separate()
|
||||
{
|
||||
separate.Raise(
|
||||
uiapp =>
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
var list = uidoc.Selection.GetElementIds();
|
||||
|
||||
if (list.Count == 0)
|
||||
{
|
||||
MessageBox.Show("未选中元素", "提示");
|
||||
return;
|
||||
}
|
||||
SpearateByIds(doc, list);
|
||||
doc.Invoke(
|
||||
ts =>
|
||||
{
|
||||
doc.Delete(list);
|
||||
},
|
||||
"删除元素");
|
||||
});
|
||||
}
|
||||
private void SpearateByIds(Document doc, ICollection<ElementId> list)
|
||||
{
|
||||
var allOthers = doc.OfModelCollector()?
|
||||
.Excluding(list)
|
||||
.ToElementIds();
|
||||
if (allOthers == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var ids = doc.OfClass<ImportInstance>().ToElementIds();
|
||||
var modelLineIds = doc.OfCollector().OfCategory(BuiltInCategory.OST_Lines).Select(e => e.Id).ToList();
|
||||
var texts = doc.OfCollector().OfCategory(BuiltInCategory.OST_TextNotes).Select(e => e.Id).ToList();
|
||||
doc.Invoke(
|
||||
ts =>
|
||||
{
|
||||
doc.Delete(allOthers);
|
||||
doc.Delete(ids);
|
||||
doc.Delete(modelLineIds);
|
||||
doc.Delete(texts);
|
||||
},
|
||||
"删除其他");
|
||||
if (!Directory.Exists(FolderPath))
|
||||
{
|
||||
Directory.CreateDirectory(FolderPath);
|
||||
}
|
||||
var filePath = Path.Combine(FolderPath, $"{FileName}.rvt");
|
||||
SaveAsOptions options = new SaveAsOptions() { OverwriteExistingFile = true, PreviewViewId = doc.ActiveView.Id, Compact = true };
|
||||
|
||||
doc.SaveAs(filePath, options);
|
||||
QuickAccessToolBarService.performMultipleUndoRedoOperations(true, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
ShrlAlgo.RvKits/ModelManager/SeparateModelWin.xaml
Normal file
37
ShrlAlgo.RvKits/ModelManager/SeparateModelWin.xaml
Normal file
@@ -0,0 +1,37 @@
|
||||
<ui:FluentWindowEx
|
||||
x:Class="ShrlAlgo.RvKits.ModelManager.SeparateModelWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
|
||||
xmlns:local="clr-namespace:ShrlAlgo.RvKits.ModelManager"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="https://github.com/ShrlAlgo/WPFluent"
|
||||
Title="拆分模型"
|
||||
Width="300"
|
||||
Height="300"
|
||||
d:DataContext="{d:DesignInstance Type=local:SeparateModelViewModel}"
|
||||
SizeToContent="Height"
|
||||
Topmost="True"
|
||||
mc:Ignorable="d">
|
||||
<ui:FluentWindowEx.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/ShrlAlgo.RvKits;component/WPFUI.xaml" />
|
||||
</ui:FluentWindowEx.Resources>
|
||||
<Grid>
|
||||
<StackPanel Margin="5">
|
||||
<ui:TextBox
|
||||
Margin="5"
|
||||
PlaceholderText="文件名"
|
||||
Text="{Binding FileName, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<ui:TextBox
|
||||
Margin="5"
|
||||
PlaceholderText="保存路径"
|
||||
Text="{Binding FolderPath, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<ui:Button
|
||||
Margin="5"
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{Binding SeparateCommand}"
|
||||
Content="拆分" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ui:FluentWindowEx>
|
||||
14
ShrlAlgo.RvKits/ModelManager/SeparateModelWin.xaml.cs
Normal file
14
ShrlAlgo.RvKits/ModelManager/SeparateModelWin.xaml.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using WPFluent.Controls;
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager;
|
||||
/// <summary>
|
||||
/// SeparateModelWin.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class SeparateModelWin : FluentWindowEx
|
||||
{
|
||||
public SeparateModelWin()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
}
|
||||
17
ShrlAlgo.RvKits/ModelManager/TemplateManagerCmd.cs
Normal file
17
ShrlAlgo.RvKits/ModelManager/TemplateManagerCmd.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Autodesk.Revit.Attributes;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager;
|
||||
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
[Regeneration(RegenerationOption.Manual)]
|
||||
internal class TemplateManagerCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
var view = new TemplateManagerView() { DataContext = new TemplateManagerViewModel() };
|
||||
view.ShowDialog();
|
||||
}
|
||||
}
|
||||
40
ShrlAlgo.RvKits/ModelManager/TemplateManagerView.xaml
Normal file
40
ShrlAlgo.RvKits/ModelManager/TemplateManagerView.xaml
Normal file
@@ -0,0 +1,40 @@
|
||||
<ui:FluentWindow
|
||||
x:Class="ShrlAlgo.RvKits.ModelManager.TemplateManagerView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ShrlAlgo.RvKits.ModelManager"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="https://github.com/ShrlAlgo/WPFluent"
|
||||
Width="800"
|
||||
Height="450"
|
||||
d:DataContext="{d:DesignInstance Type=local:TemplateManagerViewModel}"
|
||||
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
|
||||
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
mc:Ignorable="d">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/ShrlAlgo.RvKits;component/WPFUI.xaml" />
|
||||
</Window.Resources>
|
||||
<DockPanel>
|
||||
<ui:TitleBar DockPanel.Dock="Top" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel>
|
||||
<ComboBox
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding FontFamilies}"
|
||||
SelectedItem="{Binding SelectFontFamily}" />
|
||||
<TextBox Text="{Binding FontSize}" />
|
||||
<TextBox Text="{Binding WidthScale}" />
|
||||
<Button Command="{Binding ModifyFontCommand}" Content="修改字体" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</ui:FluentWindow>
|
||||
25
ShrlAlgo.RvKits/ModelManager/TemplateManagerView.xaml.cs
Normal file
25
ShrlAlgo.RvKits/ModelManager/TemplateManagerView.xaml.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager;
|
||||
/// <summary>
|
||||
/// TemplateManagerView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class TemplateManagerView
|
||||
{
|
||||
public TemplateManagerView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
159
ShrlAlgo.RvKits/ModelManager/TemplateManagerViewModel.cs
Normal file
159
ShrlAlgo.RvKits/ModelManager/TemplateManagerViewModel.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
using Nice3point.Revit.Toolkit.Options;
|
||||
|
||||
|
||||
namespace ShrlAlgo.RvKits.ModelManager;
|
||||
|
||||
public partial class TemplateManagerViewModel : ObservableObject
|
||||
{
|
||||
private readonly ActionEventHandler handler;
|
||||
[ObservableProperty]
|
||||
private FontFamily[] fontFamilies;
|
||||
[ObservableProperty]
|
||||
private FontFamily selectFontFamily;
|
||||
[ObservableProperty]
|
||||
private double fontSize;
|
||||
[ObservableProperty]
|
||||
private double widthScale;
|
||||
public TemplateManagerViewModel()
|
||||
{
|
||||
handler = new ActionEventHandler();
|
||||
// 创建 InstalledFontCollection 对象
|
||||
var installedFonts = new InstalledFontCollection();
|
||||
// 获取已安装的字体数组
|
||||
fontFamilies = installedFonts.Families;
|
||||
}
|
||||
[RelayCommand]
|
||||
private void CleanFontType()
|
||||
{
|
||||
handler.Raise(
|
||||
uiapp =>
|
||||
{
|
||||
var doc = uiapp.ActiveUIDocument.Document;
|
||||
var textTypes = doc.OfClass<TextNoteType>().ToList();
|
||||
|
||||
foreach (var type in textTypes)
|
||||
{
|
||||
{
|
||||
if (type is TextNoteType textNoteType)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
var font = textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).AsString();
|
||||
var size = textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsValueString().TrimEnd('m');
|
||||
var dSize = Math.Round(Convert.ToDouble(size), 1, MidpointRounding.AwayFromZero);
|
||||
if (dSize < 0.23)
|
||||
{
|
||||
return;
|
||||
}
|
||||
textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).SetValueString(dSize.ToString());
|
||||
var scale = textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsValueString();
|
||||
//var color = textNoteType.get_Parameter(BuiltInParameter.LINE_COLOR).AsInteger();
|
||||
var name = $"{font}-{dSize}mm-{scale}";
|
||||
var isExist = textTypes.FirstOrDefault(t => t.Name == name);
|
||||
if (isExist != null)
|
||||
{
|
||||
var texts = doc.OfClass<TextNote>().Where(e => e.GetTypeId() == textNoteType.Id).ToList();
|
||||
texts.ForEach(e => e.ChangeTypeId(isExist.Id));
|
||||
doc.Regenerate();
|
||||
doc.Delete(textNoteType.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
textNoteType.Name = name;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
[RelayCommand]
|
||||
private void ModifyFont()
|
||||
{
|
||||
handler.Raise(
|
||||
uiapp =>
|
||||
{
|
||||
var doc = uiapp.ActiveUIDocument.Document;
|
||||
doc.InvokeGroup(
|
||||
tg =>
|
||||
{
|
||||
var col = doc.OfClass<Family>()
|
||||
.Cast<Family>()
|
||||
.Where(f => f.FamilyCategory.CategoryType == CategoryType.Annotation);
|
||||
foreach (var family in col)
|
||||
{
|
||||
if (!family.IsEditable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var familyEditing = doc.EditFamily(family);
|
||||
//所有标签文字;
|
||||
familyEditing.Invoke(
|
||||
ts =>
|
||||
{
|
||||
var textElements = familyEditing.OfClass<TextElement>().Cast<TextElement>();
|
||||
foreach (var text in textElements)
|
||||
{
|
||||
var type = text.Symbol;
|
||||
ElementType typeCopy;
|
||||
try
|
||||
{
|
||||
typeCopy = type.Duplicate(
|
||||
$"{SelectFontFamily.Name} {FontSize} - {WidthScale}");
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.ArgumentException)
|
||||
{
|
||||
}
|
||||
type.get_Parameter(BuiltInParameter.TEXT_FONT)?.SetValueString(
|
||||
$"{SelectFontFamily.Name}");
|
||||
//字体大小
|
||||
type.get_Parameter(BuiltInParameter.TEXT_SIZE)?.Set(FontSize);
|
||||
//宽度系数
|
||||
type.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE)?.Set(WidthScale);
|
||||
}
|
||||
|
||||
var textNotes = familyEditing.OfClass<TextNote>().Cast<TextNote>();
|
||||
foreach (var text in textNotes)
|
||||
{
|
||||
var type = text.Symbol;
|
||||
try
|
||||
{
|
||||
var typeCopy = type.Duplicate(
|
||||
$"{SelectFontFamily.Name} {FontSize} - {WidthScale}");
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.ArgumentException)
|
||||
{
|
||||
}
|
||||
type.get_Parameter(BuiltInParameter.TEXT_FONT)?.SetValueString(
|
||||
$"{SelectFontFamily.Name}");
|
||||
//字体大小
|
||||
type.get_Parameter(BuiltInParameter.TEXT_SIZE)?.Set(FontSize);
|
||||
//宽度系数
|
||||
type.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE)?.Set(WidthScale);
|
||||
}
|
||||
});
|
||||
doc.Invoke(
|
||||
ts =>
|
||||
{
|
||||
familyEditing.LoadFamily(doc, new FamilyLoadOptions(true));
|
||||
},
|
||||
"载入族");
|
||||
}
|
||||
}, "调整文字");
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user