2025-09-16 16:06:41 +08:00
using System.Diagnostics ;
using System.Linq ;
using System.Net ;
using System.Reflection ;
using System.Text ;
using System.Windows ;
using System.Windows.Media.Imaging ;
using Autodesk.Revit.DB ;
using Autodesk.Revit.UI ;
using Autodesk.Windows ;
using AutoUpdaterDotNET ;
using Nice3point.Revit.Toolkit.External ;
using Nice3point.Revit.Toolkit.External.Handlers ;
using Szmedi.RvKits.Civil ;
using Szmedi.RvKits.Common ;
using Szmedi.RvKits.DisplayTools ;
using Szmedi.RvKits.DrawingTools ;
using Szmedi.RvKits.FamilyTools ;
using Szmedi.RvKits.InfoManager ;
using Szmedi.RvKits.InfoManager.AFCA ;
using Szmedi.RvKits.InfoManager.EAMTools ;
using Szmedi.RvKits.InfoManager.PropEditor ;
using Szmedi.RvKits.MEPTools ;
using Szmedi.RvKits.Modeling ;
using Szmedi.RvKits.ModelManager ;
using Szmedi.RvKits.Properties ;
using Szmedi.RvKits.RvScript ;
using RibbonButton = Autodesk . Windows . RibbonButton ;
using RibbonPanel = Autodesk . Revit . UI . RibbonPanel ;
namespace Szmedi.RvKits.UIApp ;
public class UIRibbon : ExternalApplication
{
private const string TabName = "SZMEDI工具" ;
private static readonly string AddInPath = GlobalVariables . AddInPath ;
private Autodesk . Windows . RibbonPanel addInManagerPanel ;
private AsyncEventHandler saveHandler ;
private UIApplication uiapp ;
//private void Updater()
//{
// Assembly assembly = Assembly.GetExecutingAssembly();
// //程序集版本
// AutoUpdater.Start("https://rbsoft.org/updates/AutoUpdaterTest.xml", assembly);
// //ftp服务器基本验证
// AutoUpdater.Start("ftp://rbsoft.org/updates/AutoUpdaterTest.xml", new NetworkCredential("FtpUserName", "FtpPassword"));
// AutoUpdater.Synchronous = true;
// AutoUpdater.ShowSkipButton = false;
// AutoUpdater.ShowRemindLaterButton = false;
// AutoUpdater.Mandatory = true;//忽略稍后提醒或跳过
// AutoUpdater.UpdateMode = Mode.Forced;//强制更新
// BasicAuthentication basicAuthentication = new("myUserName", "myPassword");
// AutoUpdater.BasicAuthXML = AutoUpdater.BasicAuthDownload = AutoUpdater.BasicAuthChangeLog = basicAuthentication;
// AutoUpdater.HttpUserAgent = "AutoUpdater";
// AutoUpdater.ReportErrors = true;
// AutoUpdater.RunUpdateAsAdmin = true;
// AutoUpdater.UpdateFormSize = new System.Drawing.Size(800, 600);
// AutoUpdater.TopMost = true;
// AutoUpdater.SetOwner(ComponentManager.ApplicationWindow);
// //定时检查更新
// DispatcherTimer timer = new() { Interval = TimeSpan.FromMinutes(2) };
// timer.Tick += delegate
// {
// AutoUpdater.Start("https://rbsoft.org/updates/AutoUpdaterTestWPF.xml");
// };
// timer.Start();
//}
// public static RadioButtonGroup ZoomRBGroup { private set; get; }
private ActionEventHandler zoomElementHandler ;
//族文档插件不可见
private void Application_ViewActivating ( object sender , Autodesk . Revit . UI . Events . ViewActivatingEventArgs e )
{
SetTabEnabled ( TabName , ! e . NewActiveView . Document . IsFamilyDocument ) ;
}
/// <summary>
/// 框选与视图中当前选择的图元类型一样的元素
/// </summary>
private void BoxSelectTheSameElemsAtCurrentView ( )
{
try
{
var uidoc = uiapp . ActiveUIDocument ;
var doc = uidoc . Document ;
var sel = uidoc . Selection ;
var selectedIds = sel . GetElementIds ( ) ;
List < ElementId > setSelectedElemIds = [ ] ;
List < Element > setSelectedElems = [ ] ;
if ( selectedIds . Count = = 0 )
{
return ;
}
foreach ( var elemId in selectedIds )
{
var selectedElement = doc . GetElement ( elemId ) ;
setSelectedElems . Add ( selectedElement ) ;
}
SelectTheSameElements selFilter = new ( setSelectedElems ) ;
var elements = uidoc . Selection . PickElementsByRectangle ( selFilter , "请框选与当前选择元素相同的实例" ) ;
setSelectedElemIds . AddRange ( elements . Select ( e = > e . Id ) ) ;
uidoc . Selection . SetElementIds ( setSelectedElemIds ) ;
}
catch ( Autodesk . Revit . Exceptions . OperationCanceledException ) { }
catch ( Exception ex )
{
MessageBox . Show ( ex . Message ) ;
LogAssists . WriteLog ( ex . StackTrace ) ;
}
}
private static void CommonApp ( RibbonPanel standardPanel )
{
PushButtonData addViewFilters =
new ( nameof ( AddViewFiltersCmd ) , "土建过滤" , AddInPath , typeof ( AddViewFiltersCmd ) . FullName )
{
LargeImage = Resources . ElementFilter_32px . ToBitmapSource ( ) ,
ToolTip = "在当前视图添加区分建筑、结构构件的默认过滤器"
} ;
PushButtonData resolveLevelPbd =
new ( nameof ( ResolveLevelCmd ) , "标高重设" , AddInPath , typeof ( ResolveLevelCmd ) . FullName )
{
LargeImage = Resources . LevelSet_32px . ToBitmapSource ( ) ,
ToolTip = "将构件按实际标高位置重设参照标高"
} ;
PushButtonData splittingPbd =
new ( nameof ( SplitComponentByLevelCmd ) , "拆分墙柱" , AddInPath , typeof ( SplitComponentByLevelCmd ) . FullName )
{
LargeImage = Resources . SplitCom_32px . ToBitmapSource ( ) ,
ToolTip = "按标高拆分墙、柱"
} ;
PushButtonData levelSeparatePbd =
new ( nameof ( LevelSeparateCmd ) , "构件划分" , AddInPath , typeof ( LevelSeparateCmd ) . FullName )
{
LargeImage = Resources . Floors_Separate_32px . ToBitmapSource ( ) ,
Image = Resources . Floors_Separate_16px . ToBitmapSource ( ) ,
ToolTip = "按标高或所属楼层对构件进行划分"
} ;
PushButtonData slopeFloorCreator =
new ( nameof ( SlopedFloorCmd ) , "坡度楼板" , AddInPath , typeof ( SlopedFloorCmd ) . FullName )
{
LargeImage = Resources . Inclination_32px . ToBitmapSource ( ) ,
ToolTip = "选择两个构件的两条平行的边线快速创建楼板"
} ;
PushButtonData resolveConnection =
new ( nameof ( ResolveCivilConnections ) , "连接构件" , AddInPath , typeof ( ResolveCivilConnections ) . FullName )
{
Image = Resources . union_16px . ToBitmapSource ( ) ,
LargeImage = Resources . union_32px . ToBitmapSource ( ) ,
ToolTip = "批量连接墙、梁、板、柱等构件"
} ;
PushButtonData room3D =
new ( nameof ( Room3D ) , "房间实体" , AddInPath , typeof ( Room3D ) . FullName )
{
Image = Resources . Room3D_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Room3D_32px . ToBitmapSource ( ) ,
ToolTip = "根据房间的高差属性,创建房间的几何实体"
} ;
PushButtonData geologyByLoop =
new ( nameof ( CutGeologyByLoopCmd ) , "地质剖切" , AddInPath , typeof ( CutGeologyByLoopCmd ) . FullName )
{
Image = Resources . GeologyBlock_16px . ToBitmapSource ( ) ,
LargeImage = Resources . GeologyBlock_32px . ToBitmapSource ( ) ,
ToolTip = "根据框选的闭合曲线,对内建的地质体模型进行剖切"
} ;
PushButtonData roomNaming =
new ( nameof ( RoomNamingCmd ) , "车站房间" , AddInPath , typeof ( RoomNamingCmd ) . FullName )
{
Image = Resources . RoomManager_16px . ToBitmapSource ( ) ,
LargeImage = Resources . RoomManager_32px . ToBitmapSource ( ) ,
ToolTip = "快速修改房间名" ,
LongDescription = "将房间名修改为车站房间名,如:站台、候车室、售票处等"
} ;
PushButtonData roomNameAssign =
new ( nameof ( RoomNameAssignCmd ) , "房间命名" , AddInPath , typeof ( RoomNameAssignCmd ) . FullName )
{
Image = Resources . DWGRoomRename_16px . ToBitmapSource ( ) ,
LargeImage = Resources . DWGRoomRename_32px . ToBitmapSource ( ) ,
ToolTip = "根据CAD图纸的图层名称命名" ,
LongDescription = "布置好房间, 在平面视图中, 链接CAD图纸(注:房间名不是文字或多行文字需要炸开),对齐到模型,拾取文字,自动改名。" ,
AvailabilityClassName = typeof ( EnableOnPlan ) . FullName
} ;
PushButtonData roomBatch =
new ( nameof ( RoomsBatchCmd ) , "房间设置" , AddInPath , typeof ( RoomsBatchCmd ) . FullName )
{
Image = Resources . RoomBatch_16px . ToBitmapSource ( ) ,
LargeImage = Resources . RoomBatch_32px . ToBitmapSource ( ) ,
ToolTip = "批量修改房间属性,统计" ,
LongDescription = "批量修改房间的标高,获取体积"
} ;
PushButtonData resetCoordinate =
new ( nameof ( ResetCoordinateCmd ) , "重置基点" , AddInPath , typeof ( ResetCoordinateCmd ) . FullName )
{
LargeImage = Resources . Reset_32px . ToBitmapSource ( ) ,
ToolTip = "批量处理项目基点清零"
} ;
PushButtonData moveModel =
new ( nameof ( MoveModelCmd ) , "移动模型" , AddInPath , typeof ( MoveModelCmd ) . FullName )
{
LargeImage = Resources . MoveModel_32px . ToBitmapSource ( ) ,
ToolTip = "在平、立面、剖面视图下移动全部模型" ,
2025-12-23 21:37:02 +08:00
LongDescription = "部分图元无法移动或移动会错位,需手动处理,如:基于面放置的族实例等,如果发生严重错误,如部分草图楼梯移动发生严重错误,可以尝试剪切粘贴后再使用此命令" ,
2025-09-16 16:06:41 +08:00
AvailabilityClassName = typeof ( EnableOnPlanOrSection ) . FullName
} ;
PushButtonData getCoordinate =
new ( nameof ( GetBasePointInfoCmd ) , "获取基点" , AddInPath , typeof ( GetBasePointInfoCmd ) . FullName )
{
LargeImage = Resources . Coordinate_32px . ToBitmapSource ( ) ,
ToolTip = "获取项目基点"
} ;
PushButtonData materialProcess =
new ( nameof ( MaterialBatchCmd ) , "土建材质" , AddInPath , typeof ( MaterialBatchCmd ) . FullName )
{
LargeImage = Resources . Material_32px . ToBitmapSource ( ) ,
ToolTip = "土建构件的材质赋予、统一、查找发光材质"
} ;
PushButtonData renameType =
new ( nameof ( RenameTypeNameCmd ) , "重命名\n类型名" , AddInPath , typeof ( RenameTypeNameCmd ) . FullName )
{
LargeImage = Resources . Rename_32px . ToBitmapSource ( ) ,
ToolTip = "批量重命名族类型"
} ;
PushButtonData renameFamily =
new ( nameof ( RenameFamilyNameCmd ) , "重命名\n族名" , AddInPath , typeof ( RenameFamilyNameCmd ) . FullName )
{
LargeImage = Resources . RenameFull_32px . ToBitmapSource ( ) ,
ToolTip = "批量重命名族名称"
} ;
PushButtonData modelReviewPbd =
new ( nameof ( ModelReviewCmd ) , "模型审查" , AddInPath , typeof ( ModelReviewCmd ) . FullName )
{
LargeImage = Resources . model_review_32px . ToBitmapSource ( ) ,
ToolTip = "对项目文件,进行项目定位、命名、属性信息的审查,并出审核报告" ,
LongDescription = "对项目定位、命名、属性信息、机电管线问题进行审核"
} ;
PushButtonData modelCheckPbd =
new ( nameof ( ModelCheckCmd ) , "模型检查" , AddInPath , typeof ( ModelCheckCmd ) . FullName )
{
LargeImage = Resources . model_check_32px . ToBitmapSource ( ) ,
ToolTip = "对模型进行多项要求的检查"
} ;
PushButtonData dwgBlockModelCreator =
new ( nameof ( InstanceCreatorCmd ) , "实例布置" , AddInPath , typeof ( InstanceCreatorCmd ) . FullName )
{
//Image = ConvertFromBitmap(Resources.cmd_16px),
LargeImage = Resources . ModelCreator_32px . ToBitmapSource ( ) ,
ToolTip = "拾取dwg块布置族实例" ,
LongDescription = "拾取dwg块布置实例, 可选填参数值" ,
AvailabilityClassName = typeof ( EnableOnPlan ) . FullName
} ;
PushButtonData trackCreator =
new ( nameof ( TrackCreatorCmd ) , "曲线布置" , AddInPath , typeof ( TrackCreatorCmd ) . FullName )
{
Image = Resources . Track_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Track_32px . ToBitmapSource ( ) ,
ToolTip = "沿曲线布置实例、创建放样,可用于轨道创建、轨枕、扣件的布置" ,
LongDescription = "1.选择合适的轮廓族(可选)或可载入的点定位族(可选)\n2.选择合适的材质(可选)\n3.设置基于放样线截面的相对位置关系\n4.选择连续的放样线,并完成选择"
} ;
PushButtonData pureModel =
new ( nameof ( PureModelCmd ) , "清理\n未使用项" , AddInPath , typeof ( PureModelCmd ) . FullName )
{
LargeImage = Resources . Pure_Model_32px . ToBitmapSource ( ) ,
ToolTip = "清理未使用项,并压缩保存项目文件"
} ;
PushButtonData setDisplay =
new ( nameof ( SetModelDisplayCmd ) , "清理\n分析图元" , AddInPath , typeof ( SetModelDisplayCmd ) . FullName )
{
LargeImage = Resources . Clear_32px . ToBitmapSource ( ) ,
ToolTip = "取消构件的分析模型和删除辅助模型线、参照线等图元"
} ;
PushButtonData parameterManager =
new ( nameof ( ParamManagerCmd ) , "参数管理" , AddInPath , typeof ( ParamManagerCmd ) . FullName )
{
//Image = ConvertFromBitmap(Resources.cmd_16px),
LargeImage = Resources . ParameterManager_32px . ToBitmapSource ( ) ,
ToolTip = "交付标准及自定义的参数批处理添加、修改参数、修改参数值" ,
AvailabilityClassName = typeof ( OnActiveProjectDocument ) . FullName
} ;
PushButtonData eamManager =
new ( nameof ( EAMCodingCmd ) , "EAM设备表" , AddInPath , typeof ( EAMCodingCmd ) . FullName )
{
Image = Resources . EAM_Code_16px . ToBitmapSource ( ) ,
LargeImage = Resources . EAM_Code_32px . ToBitmapSource ( ) ,
ToolTip = "运营提供的EAM设备表( Excel) 匹配及编码写入" ,
} ;
PushButtonData eamCodeManager =
new ( nameof ( EAMFacilityCodeCmd ) , "EAM编码填写" , AddInPath , typeof ( EAMFacilityCodeCmd ) . FullName )
{
Image = Resources . CodeList_16px . ToBitmapSource ( ) ,
LargeImage = Resources . CodeList_32px . ToBitmapSource ( ) ,
ToolTip = "运营提供的EAM设备表便捷填写、更新编码" ,
} ;
PushButtonData eamCheck =
new ( nameof ( EAMCodeCheckCmd ) , "EAM编码检查" , AddInPath , typeof ( EAMCodeCheckCmd ) . FullName )
{
Image = Resources . EAM_Code_Check_16px . ToBitmapSource ( ) ,
LargeImage = Resources . EAM_Code_Check_32px . ToBitmapSource ( ) ,
ToolTip = "检查模型中的EAM编码是否有误" ,
} ;
PushButtonData mappingManager =
new ( nameof ( MappingElementCodeCmd ) , "属性匹配" , AddInPath , typeof ( MappingElementCodeCmd ) . FullName )
{
Image = Resources . PropertyMatch_16px . ToBitmapSource ( ) ,
LargeImage = Resources . PropertyMatch_32px . ToBitmapSource ( ) ,
ToolTip = "根据目标属性, 匹配属性值相同的族实例并写入Excel中属性的值, 仅支持可载入族。" ,
LongDescription = "所有的属性会使用Excel中的值完全覆盖"
} ;
PushButtonData parameterWriter =
new ( nameof ( WriteParametersCmd ) , "参数填写" , AddInPath , typeof ( WriteParametersCmd ) . FullName )
{
LargeImage = Resources . WriteParameters_32px . ToBitmapSource ( ) ,
ToolTip = "修改族实例参数值,请在三维视图中使用" ,
LongDescription = "对三维视图可见(临时隐藏也算不可见)\n的三维元素进行修改实例参数值,请切换到三维视图使用" ,
AvailabilityClassName = typeof ( EnableOnView3d ) . FullName
} ;
PushButtonData relacePropValue =
new ( nameof ( ReplaceParamValueCmd ) , "参数值替换" , AddInPath , typeof ( ReplaceParamValueCmd ) . FullName )
{
Image = Resources . Replace_Sub_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Replace_Sub_32px . ToBitmapSource ( ) ,
ToolTip = "对选中元素的某个参数的参数值,查找字段并修改" ,
} ;
PushButtonData removeProps =
new ( nameof ( RemoveParamsCmd ) , "参数移除" , AddInPath , typeof ( RemoveParamsCmd ) . FullName )
{
Image = Resources . Remove_Params_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Remove_Params_32px . ToBitmapSource ( ) ,
ToolTip = "对元素的某些参数进行移除" ,
} ;
PushButtonData writeFacilityCode =
new ( nameof ( WriteFacilityCodeCmd ) , "设备编号" , AddInPath , typeof ( WriteFacilityCodeCmd ) . FullName )
{
//Image = ConvertFromBitmap(Resources.cmd_16px),
LargeImage = Resources . WriteFacilityCode_32px . ToBitmapSource ( ) ,
ToolTip = "设备编号提取、写入" ,
} ;
2025-12-23 21:37:02 +08:00
PushButtonData writeFacilityInfo =
new ( nameof ( FacilityInfoProcessCmd ) , "设备信息" , AddInPath , typeof ( FacilityInfoProcessCmd ) . FullName )
{
//Image = ConvertFromBitmap(Resources.cmd_16px),
LargeImage = Resources . Facility_Info_Process_32px . ToBitmapSource ( ) ,
ToolTip = "给设备构件批量添加信息" ,
LongDescription = "Excel需要包含设备、设备参数、部署范围三列, 设备参数列的每个单元格中每行一个参数, 参数表达例如“品牌: 日立”"
} ;
2025-09-16 16:06:41 +08:00
PushButtonData afcaMetroManager =
new ( nameof ( AFCAMetroCmd ) , "轨交交付" , AddInPath , typeof ( AFCAMetroCmd ) . FullName )
{
LargeImage = Resources . AFCAMetro_32px . ToBitmapSource ( ) ,
ToolTip = "按轨道交通交付标准要求,添加、填写、修改属性" ,
AvailabilityClassName = typeof ( OnActiveProjectDocument ) . FullName
} ;
2025-12-23 21:37:02 +08:00
2025-09-16 16:06:41 +08:00
standardPanel . AddSplitButton ( new ( "土建工具" , "土建工具" ) , geologyByLoop , resolveLevelPbd , levelSeparatePbd , splittingPbd , slopeFloorCreator , resolveConnection , addViewFilters ) ;
standardPanel . AddSplitButton ( new ( "房间功能" , "房间功能" ) , room3D , roomNaming , roomNameAssign ) ;
standardPanel . AddSplitButton ( new ( "基点功能" , "基点功能" ) , resetCoordinate , getCoordinate , moveModel ) ;
standardPanel . AddItem ( materialProcess ) ;
standardPanel . AddSplitButton ( new ( "重命名功能" , "重命名功能" ) , renameType , renameFamily ) ;
//standardPanel.AddItem(resolveConnection);
standardPanel . AddSplitButton ( new ( "模型检查" , "模型检查" ) , modelReviewPbd , modelCheckPbd , eamCheck ) ;
standardPanel . AddSplitButton ( new ( "布置工具" , "布置工具" ) , trackCreator , dwgBlockModelCreator ) ;
//standardPanel.AddItem(dwgBlockModelCreator);
//standardPanel.AddItem(trackCreator);
standardPanel . AddSplitButton ( new ( "清理工具" , "清理工具" ) , pureModel , setDisplay ) ;
2025-12-23 21:37:02 +08:00
standardPanel . AddSplitButton ( new ( "参数管理" , "参数管理" ) , parameterManager , afcaMetroManager , eamManager , eamCodeManager , mappingManager , writeFacilityCode , writeFacilityInfo ) ;
2025-09-16 16:06:41 +08:00
standardPanel . AddSplitButton ( new ( "参数修改" , "参数修改" ) , parameterWriter , relacePropValue , removeProps ) ;
//standardPanel.AddSplitButton(new("交付管理", "交付管理"), afcaMetroManager, afcaArchiManager);
2025-12-23 21:37:02 +08:00
//standardPanel.AddItem(afcaMetroManager);
2025-09-16 16:06:41 +08:00
}
private void ComponentManager_UIElementActivated ( object sender , UIElementActivatedEventArgs e )
{
if ( e is { Item . Id : not null } )
{
if ( e . Item . Id = = "ID_IAV_BTN" ) //e.Item.Id这里绑定按钮Id执行相应事件
{
SelectTheSameElementsAtCurrentView ( ) ;
}
else if ( e . Item . Id = = "ID_IIP_BTN" )
{
SelectTheSameElementsInTheProject ( ) ;
}
else if ( e . Item . Id = = "ID_BS_BTN" )
{
BoxSelectTheSameElemsAtCurrentView ( ) ;
}
}
}
private void ControlledApplication_ApplicationInitialized ( object sender , Autodesk . Revit . DB . Events . ApplicationInitializedEventArgs e )
{
InsertQuickAccessAndHidePanel ( ) ;
//Properties.Settings.Default.TimerSubscribed = false;
//Properties.Settings.Default.Save();
var currentVersion = Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version . ToString ( ) ;
var savedVersion = Properties . Settings . Default . LastVersion ;
if ( currentVersion ! = savedVersion )
{
// 显示更新内容提示
ShowUpdateMessage ( ) ;
// 更新存储的版本信息
Properties . Settings . Default . LastVersion = currentVersion ;
Properties . Settings . Default . Save ( ) ;
}
}
private void CreateModifyUI ( )
{
var tab = ComponentManager . Ribbon . Tabs . First ( t = > t . Id = = "Modify" ) ;
if ( tab . Id = = "Modify" ) //将按钮嵌入到修改选项卡上
{
Autodesk . Windows . RibbonPanel selElesPanel = new ( ) ;
//{
// FloatingOrientation = System.Windows.Controls.Orientation.Vertical
//}
RibbonPanelSource selSource = new ( ) { Id = "ID_SSI_Panel" , Title = "选择" } ;
selElesPanel . Source = selSource ;
RibbonButton iavBtn =
new ( )
{
Image = Resources . Select_View_16px . ToBitmapSource ( ) ,
//LargeImage = ConvertFromBitmap(Resources.Select_View_32px),
ShowImage = true ,
//Size = RibbonItemSize.Large,
ShowText = true ,
Id = "ID_IAV_BTN" ,
Name = "选择视图中全部实例" ,
Text = "选择视图中全部实例" ,
IsEnabled = true ,
IsVisible = true ,
IsCheckable = true
//Orientation = System.Windows.Controls.Orientation.Horizontal
} ;
RibbonButton iipBtn =
new ( )
{
Image = Resources . Select_Project_16px . ToBitmapSource ( ) ,
//LargeImage = ConvertFromBitmap(Resources.Select_32px),
ShowImage = true ,
//Size = RibbonItemSize.Large,
ShowText = true ,
Id = "ID_IIP_BTN" ,
//下拉显示名
Name = "选择项目中全部实例" ,
//选中显示名
Text = "选择项目中全部实例" ,
IsEnabled = true ,
IsVisible = true ,
IsCheckable = true
//Orientation = System.Windows.Controls.Orientation.Horizontal
} ;
RibbonButton rSelBtn =
new ( )
{
Image = Resources . Select_Selected_16px . ToBitmapSource ( ) ,
//LargeImage = ConvertFromBitmap(Resources.Select_Object_32px),
ShowImage = true ,
//Size = RibbonItemSize.Large,
ShowText = true ,
Id = "ID_BS_BTN" ,
//下拉显示名
Name = "选取当前选择相同实例" ,
//选中显示名
Text = "选取当前选择相同实例" ,
IsEnabled = true ,
IsVisible = true ,
IsCheckable = true
//Orientation = System.Windows.Controls.Orientation.Horizontal
} ;
//面板行布局
RibbonRowPanel ribbonRowPanel = new ( ) ;
ribbonRowPanel . Items . Add ( iavBtn ) ;
//行打断=新建行
ribbonRowPanel . Items . Add ( new RibbonRowBreak ( ) ) ;
ribbonRowPanel . Items . Add ( iipBtn ) ;
ribbonRowPanel . Items . Add ( new RibbonRowBreak ( ) ) ;
ribbonRowPanel . Items . Add ( rSelBtn ) ;
//面板按钮
Autodesk . Windows . RibbonButton selFilterBtn =
new ( )
{
//Image = new System.Windows.Media.Imaging.BitmapImage(new Uri(icopath)),
Image = Resources . select_filter_16px . ToBitmapSource ( ) ,
LargeImage = Resources . select_filter_32px . ToBitmapSource ( ) ,
Size = RibbonItemSize . Large ,
ShowText = true ,
Id = "ID_Filter_BTN" ,
Name = "构件明细" ,
ToolTip = "查看选中的元素" ,
Text = "构件明细" ,
IsCheckable = true ,
Orientation = System . Windows . Controls . Orientation . Vertical ,
CommandHandler = new RelayCommand (
( ) = > WinDialogAssists . ShowOrActivate < DetailSelectFiltersView , DetailSelectFiltersViewModel > ( UiApplication ) ,
( ) = >
UiApplication . ActiveUIDocument ? . Selection
. GetElementIds ( )
. Any ( id = > UiApplication . ActiveUIDocument . Document . GetElement ( id ) . GetTypeId ( ) ! = ElementId . InvalidElementId & & UiApplication . ActiveUIDocument . Document . GetElement ( id ) . Category ! = null )
= = true
)
} ;
Autodesk . Windows . RibbonRowPanel selPanel = new Autodesk . Windows . RibbonRowPanel ( ) ;
selPanel . Items . Add ( selFilterBtn ) ;
selSource . Items . Add ( selPanel ) ;
selSource . Items . Add ( ribbonRowPanel ) ;
ComponentManager . UIElementActivated + = ComponentManager_UIElementActivated ;
tab . Panels . Add ( selElesPanel ) ;
}
}
private void CreateRibbonUI ( UIControlledApplication application )
{
application . CreateRibbonTab ( TabName ) ;
var familyUtilPanel = application . CreateRibbonPanel ( TabName , "族工具" ) ;
//在面板上添加添加浏览族库按钮
PushButtonData localFamilyPbd =
new ( nameof ( LocalFamsLibCmd ) , "本地族库" , AddInPath , typeof ( LocalFamsLibCmd ) . FullName ) { LargeImage = Resources . Library_32px . ToBitmapSource ( ) } ;
PushButtonData familyTransmitPbData =
new ( nameof ( TransmitFamilyCmd ) , "族传递" , AddInPath , typeof ( TransmitFamilyCmd ) . FullName )
{
Image = Resources . One_Way_Transition_16px . ToBitmapSource ( ) ,
LargeImage = Resources . One_Way_Transition_32px . ToBitmapSource ( ) ,
ToolTip = "族文件在项目中传递"
} ;
PushButtonData familyMassSavePbData =
new ( nameof ( MassSaveFamiliesCmd ) , "批量保存" , AddInPath , typeof ( MassSaveFamiliesCmd ) . FullName )
{
Image = Resources . Save_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Save_32px . ToBitmapSource ( ) ,
ToolTip = "将项目中的族保存在本地磁盘"
} ;
PushButtonData pbdFamilyInfoExport =
new ( nameof ( ComponentInfoCmd ) , "批量导出" , AddInPath , typeof ( ComponentInfoCmd ) . FullName )
{
Image = Resources . Export_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Export_32px . ToBitmapSource ( ) ,
ToolTip = "将族图片、族参数进行导出"
} ;
PushButtonData pbdFamilyReplace = new ( nameof ( ReplaceInstanceCmd ) , "实例替换" , AddInPath , typeof ( ReplaceInstanceCmd ) . FullName )
{
Image = Resources . replace_instance_16px . ToBitmapSource ( ) ,
LargeImage = Resources . replace_instance_32px . ToBitmapSource ( ) ,
ToolTip = "将点布置的族实例替换,并保留原实例的参数值到新的实例(若存在)"
} ;
PushButtonData pbdQueryExport = new ( nameof ( QueryExportCmd ) , "查询导出" , AddInPath , typeof ( QueryExportCmd ) . FullName )
{
Image = Resources . query_export_16px . ToBitmapSource ( ) ,
LargeImage = Resources . query_export_32px . ToBitmapSource ( ) ,
ToolTip = "根据查询族实例属性值,并导出数据或导出选中明细表"
} ;
familyUtilPanel . AddItem ( localFamilyPbd ) ;
familyUtilPanel . AddStackedItems ( familyTransmitPbData , familyMassSavePbData , pbdFamilyInfoExport ) ;
familyUtilPanel . AddStackedItems ( pbdFamilyReplace , pbdQueryExport ) ;
//常规
var standardPanel = application . CreateRibbonPanel ( TabName , "常规" ) ;
CommonApp ( standardPanel ) ;
var decorationPanel = application . CreateRibbonPanel ( TabName , "装修" ) ;
DecorationApp ( decorationPanel ) ;
var ribbonPanel = application . CreateRibbonPanel ( TabName , "机电工具" ) ;
MEPApp ( ribbonPanel ) ;
//standardPanel.AddStackedItems(addViewFilters, resolveLevelPbd, splittingPbd);
//standardPanel.AddSeparator();
//standardPanel.AddStackedItems(resolveConnection, setDisplay);
var dimensionPanel = application . CreateRibbonPanel ( TabName , "注释" ) ;
AnnotationApp ( dimensionPanel ) ;
var displayPanel = application . CreateRibbonPanel ( TabName , "外观" ) ;
DisplayApp ( displayPanel ) ;
var generalPanel = application . CreateRibbonPanel ( TabName , "其他" ) ;
2025-12-23 21:37:02 +08:00
PushButtonData compareProject =
new ( nameof ( CompareProjectDiffCmd ) , "文档比较" , AddInPath , typeof ( CompareProjectDiffCmd ) . FullName )
{
Image = Resources . compare_project_16px . ToBitmapSource ( ) ,
LargeImage = Resources . compare_project_32px . ToBitmapSource ( ) ,
ToolTip = "对比两个文档之间的构件差异" ,
AvailabilityClassName = typeof ( OnActiveProjectDocument ) . FullName
} ;
2025-09-16 16:06:41 +08:00
PushButtonData elementsControlPbData =
new ( nameof ( ElementsControlCmd ) , "对象控制" , AddInPath , typeof ( ElementsControlCmd ) . FullName )
{
LargeImage = Resources . Control_Panel_32px . ToBitmapSource ( )
} ;
PushButtonData categoryControlPbData =
new ( nameof ( CategoryDisplayCmd ) , "类别显示" , AddInPath , typeof ( CategoryDisplayCmd ) . FullName )
{
LargeImage = Resources . Category_Displayer_32px . ToBitmapSource ( ) ,
AvailabilityClassName = typeof ( OnActiveProjectDocument ) . FullName
} ;
PushButtonData autoSave =
new ( nameof ( AutoSaveDocumentCmd ) , "自动保存" , AddInPath , typeof ( AutoSaveDocumentCmd ) . FullName )
{
LargeImage = Resources . Document_Autosave_32px . ToBitmapSource ( ) ,
ToolTip = "自动保存文件"
} ;
PushButtonData csharpScriptDock =
new ( nameof ( ScriptRunnerCmd ) , "C#脚本执行" , AddInPath , typeof ( ScriptRunnerCmd ) . FullName )
{
Image = Resources . csharp_16px . ToBitmapSource ( ) ,
LargeImage = Resources . csharp_32px . ToBitmapSource ( ) ,
ToolTip = "执行C#脚本"
} ;
//PushButtonData csharpScript =
// new(nameof(OpenScriptPadCommand), "C#脚本执行", AddInPath, typeof(OpenScriptPadCommand).FullName)
// {
// LargeImage = Resources.Document_Autosave_32px.ToBitmapSource(),
// ToolTip = "执行C#脚本"
// };
PushButtonData releaseNote =
new ( nameof ( ReleaseNotesCmd ) , "更新内容" , AddInPath , typeof ( ReleaseNotesCmd ) . FullName )
{
LargeImage = Resources . ReleaseNote_32px . ToBitmapSource ( ) ,
ToolTip = $"当前版本:{Assembly.GetExecutingAssembly().GetName().Version}"
} ;
var tab = RibbonControl . Tabs . First ( t = > t . Name = = TabName ) ;
SetTabControl ( tab ) ;
//ElementsControlPBData.LargeImage = ConvertFromBitmap(Resources.Control_Panel_32px);
//ZoomRBGroup = CreateViewToggleButton(generalPanel);
CreateToggleButton ( tab , "其他" ) ;
2025-12-23 21:37:02 +08:00
generalPanel . AddItem ( compareProject ) ;
2025-09-16 16:06:41 +08:00
generalPanel . AddSplitButton ( new ( "显示控制" , "显示控制" ) , categoryControlPbData , elementsControlPbData ) ;
//generalPanel.AddItem(categoryControlPbData);
generalPanel . AddItem ( autoSave ) ;
//generalPanel.AddItem(csharpScript);
generalPanel . AddItem ( csharpScriptDock ) ;
generalPanel . AddItem ( releaseNote ) ;
}
private void CreateToggleButton ( Autodesk . Windows . RibbonTab rt , string panelName )
{
try
{
var panel = rt . Panels . FirstOrDefault ( p = > p . Source . Name = = panelName ) ;
var tog = new Autodesk . Windows . RibbonToggleButton ( )
{
LargeImage = Resources . zoom_32px . ToBitmapSource ( ) ,
Size = RibbonItemSize . Large ,
Name = "ZoomElement" ,
Text = "最大化" ,
ShowText = true ,
ToolTip = "根据视图的图元是否可见,在切换视图时,对当前选中的图元进行快速缩放定位" ,
IsCheckable = true ,
Orientation = System . Windows . Controls . Orientation . Vertical
} ;
tog . CheckStateChanged + = ( s , e ) = >
{
zoomElementHandler . Raise (
uiapp = >
{
if ( tog . CheckState = = true )
{
uiapp . ViewActivated - = UiApp_ViewActivated ;
uiapp . ViewActivated + = UiApp_ViewActivated ;
}
else
{
uiapp . ViewActivated - = UiApp_ViewActivated ;
}
} ) ;
} ;
//Autodesk.Windows.RibbonItemControl
panel . Source . Items . Add ( tog ) ;
tog . IsChecked = true ;
}
catch ( Exception )
{
throw ;
}
}
private static void DecorationApp ( RibbonPanel decorationPanel )
{
PushButtonData floorFinishesPbd =
new ( nameof ( FloorFinishesCmd ) , "房间饰面" , AddInPath , typeof ( FloorFinishesCmd ) . FullName )
{
LargeImage = Resources . tites_32px . ToBitmapSource ( ) ,
ToolTip = "创建房间饰面"
} ;
PushButtonData curtainFinishesPbd =
new ( nameof ( BricksFinishesCmd ) , "铺贴饰面" , AddInPath , typeof ( BricksFinishesCmd ) . FullName )
{
LargeImage = Resources . finishes_32px . ToBitmapSource ( ) ,
ToolTip = "创建铺贴饰面"
} ;
PushButtonData wallFinishesPbd =
new ( nameof ( WallFinishesCmd ) , "墙饰面" , AddInPath , typeof ( WallFinishesCmd ) . FullName )
{
LargeImage = Resources . bricks_32px . ToBitmapSource ( ) ,
ToolTip = "创建墙饰面"
} ;
decorationPanel . AddItem ( floorFinishesPbd ) ;
decorationPanel . AddItem ( curtainFinishesPbd ) ;
decorationPanel . AddItem ( wallFinishesPbd ) ;
}
static BitmapSource GetEmbeddedImage ( string name )
{
try
{
Assembly a = Assembly . GetExecutingAssembly ( ) ;
using ( var s = a . GetManifestResourceStream ( name ) )
{
return BitmapFrame . Create ( s ) ;
}
}
catch
{
return null ;
}
}
private static bool IsVisible ( ElementId viewId , Element elem )
{
if ( FilteredElementCollector . IsViewValidForElementIteration ( elem . Document , viewId ) ) // 某类视图不能使用 FilteredElementCollector
{
var fec = new FilteredElementCollector ( elem . Document , viewId ) . ToElementIds ( ) ;
return fec . Any ( id = > id = = elem . Id ) ;
}
return false ;
}
private void OnTimedEvent ( object source , System . Timers . ElapsedEventArgs e )
{
saveHandler . RaiseAsync ( app = >
{
var doc = app . ActiveUIDocument . Document ;
#if REVIT2018
if ( doc . IsModified & & ! string . IsNullOrEmpty ( doc . PathName ) )
#else
if ( ! doc . IsBackgroundCalculationInProgress ( ) & & doc . IsModified & & ! string . IsNullOrEmpty ( doc . PathName ) )
#endif
{
try
{
doc . Save ( ) ;
}
catch ( Autodesk . Revit . Exceptions . OperationCanceledException )
{
MessageBox . Show ( "已手动取消本次保存" , "提示" ) ;
}
catch ( Exception )
{
var command = RevitCommandId . LookupPostableCommandId ( PostableCommand . Save ) ;
app . PostCommand ( command ) ;
//MessageBox.Show("本次自动保存失败,将重新计时", "提示");
}
}
} ) ;
}
private static void RegisterDockPaneAndEvent ( UIControlledApplication application )
{
ElementsControlDock pane = new ( ) ;
application . RegisterDockablePane ( GlobalVariables . PaneId , "对象控制菜单" , pane ) ;
}
private void RibbonToggleButton_CheckStateChanged ( object sender , EventArgs e )
{
if ( sender is RibbonToggleButton toggleButton )
{
var tabName = toggleButton . Name ;
var tab = RibbonControl . FindTab ( tabName ) ;
tab . IsVisible = toggleButton . IsChecked ;
}
}
/// <summary>
/// 当前视图实例
/// </summary>
private void SelectTheSameElementsAtCurrentView ( )
{
try
{
var uidoc = uiapp . ActiveUIDocument ;
var doc = uidoc . Document ;
var selectedTypes = uidoc . Selection . GetElementIds ( ) . Select ( doc . GetElement ) . GroupBy ( e = > e . GetTypeId ( ) ) ;
if ( ! selectedTypes . Any ( ) )
{
return ;
}
ICollection < ElementId > setSelIds = [ ] ;
var col = new FilteredElementCollector ( doc , uidoc . ActiveView . Id ) . WhereElementIsNotElementType ( ) ;
foreach ( var group in selectedTypes )
{
foreach ( var item in col )
{
if ( group . Key = = item . GetTypeId ( ) & & item . Category ! = null )
{
setSelIds . Add ( item . Id ) ;
}
}
}
uidoc . Selection . SetElementIds ( setSelIds ) ;
}
catch ( Exception ex )
{
MessageBox . Show ( ex . Message ) ;
LogAssists . WriteLog ( $"{ex.Source}:{ex.StackTrace}" ) ;
}
}
/// <summary>
/// 项目中实例
/// </summary>
private void SelectTheSameElementsInTheProject ( )
{
try
{
var uidoc = uiapp . ActiveUIDocument ;
var doc = uidoc . Document ;
var selectedTypes = uidoc . Selection . GetElementIds ( ) . Select ( id = > doc . GetElement ( id ) ) . GroupBy ( e = > e . GetTypeId ( ) ) ;
if ( ! selectedTypes . Any ( ) )
{
return ;
}
ICollection < ElementId > setSelIds = [ ] ;
var col = new FilteredElementCollector ( doc ) . WhereElementIsNotElementType ( ) ;
foreach ( var group in selectedTypes )
{
foreach ( var item in col )
{
if ( group . Key = = item . GetTypeId ( ) & & item . Category ! = null )
{
setSelIds . Add ( item . Id ) ;
}
}
}
uidoc . Selection . SetElementIds ( setSelIds ) ;
}
catch ( Exception ex )
{
MessageBox . Show ( ex . Message ) ;
LogAssists . WriteLog ( ex . StackTrace ) ;
}
}
/// <summary>
/// 插件管理
/// </summary>
/// <param name="customRibbonTab"></param>
private void SetTabControl ( RibbonTab customRibbonTab )
{
addInManagerPanel = new Autodesk . Windows . RibbonPanel { FloatingOrientation = System . Windows . Controls . Orientation . Horizontal } ;
//面板资源
RibbonPanelSource panelSource = new ( ) { Id = "ID_AddIn_Panel" , Title = "插件管理" } ;
//面板源设置
addInManagerPanel . Source = panelSource ;
RibbonChecklistButton checklist =
new ( )
{
Id = "Id_AddIns_ListBtn" ,
Text = "插件管理" ,
Name = "插件管理" ,
Description = "控制插件在Revit界面上的是否显示" ,
Image = Resources . Addin_16px . ToBitmapSource ( ) ,
//LargeImage = ConvertFromBitmap(Resources.Select_View_16px),
ShowText = true ,
ShowImage = true ,
ToolTip = "控制插件在Revit界面上的是否显示" ,
IsToolTipEnabled = true ,
IsVisible = true ,
IsEnabled = true ,
Size = RibbonItemSize . Standard ,
AllowInToolBar = true ,
AllowInStatusBar = true ,
IsCheckable = true
} ;
var ribbon = ComponentManager . Ribbon ;
foreach ( var tab in ribbon . Tabs )
{
if ( tab . GetType ( ) = = typeof ( RibbonTab ) & & tab . Title ! = TabName )
{
RibbonToggleButton ribbonToggleButton =
new ( )
{
//Image = ConvertFromBitmap(Resources.Select_View_16px),
//LargeImage = ConvertFromBitmap(Resources.Select_View_32px),
//ShowImage = true,
Size = RibbonItemSize . Standard ,
ShowText = true ,
Id = $"Id_{tab.Title}_Tog" ,
Name = tab . Title ,
Text = tab . Title ,
IsEnabled = true ,
IsVisible = true ,
IsCheckable = true ,
IsThreeState = false ,
IsChecked = true
//CheckStateBinding = new System.Windows.Data.Binding()
//{
// Source = tab,
// Path = new PropertyPath(tab.IsVisible),
//},
//CommandHandler = new RelayCommand<object>((obj) =>
//{
// if (obj is Autodesk.Windows.RibbonButton rb)
// {
// string tabName = rb.CommandParameter.ToString();
// var ribbonTab = ribbon.FindTab(tabName);
// ribbonTab.IsVisible = true;
// }
//}),
//CommandParameter = tab.Name
//Orientation = System.Windows.Controls.Orientation.Horizontal
} ;
ribbonToggleButton . CheckStateChanged + = RibbonToggleButton_CheckStateChanged ;
checklist . Items . Add ( ribbonToggleButton ) ;
}
}
////布局
//RibbonRowPanel ribbonRowPanel = new RibbonRowPanel();
////按钮添加到流布局
//ribbonRowPanel.Items.Add(checklist);
//添加到绑定源
panelSource . Items . Add ( checklist ) ;
customRibbonTab . Panels . Add ( addInManagerPanel ) ;
//source.AddStandardItem(checklist);
}
//族文档插件不可见
private void SetTabEnabled ( string tabName , bool isVisible )
{
//Autodesk.Windows.RibbonControl ribbon = Autodesk.Windows.ComponentManager.Ribbon;
var ribbonTab = RibbonControl . FindTab ( tabName ) ;
ribbonTab . IsVisible = isVisible ;
}
private void ShowUpdateMessage ( )
{
// 在此处显示更新内容提示
var col = Properties . Settings . Default . UpdateNotes ;
var sb = new StringBuilder ( ) ;
foreach ( var item in col )
{
sb . AppendLine ( item ) ;
}
MessageBox . Show ( $"{sb}" , "SZMEDI工具更新内容" , MessageBoxButton . OK , MessageBoxImage . Information ) ;
}
//private static void NotificationUpdate()
//{
// if (Properties.Settings.Default.Notification == true)
// {
// System.Collections.Specialized.StringCollection collection = Properties.Settings.Default.UpdateNote;
// var sb = new StringBuilder();
// foreach (string str in collection)
// {
// Regex regex = new("^(\\d+.){3}\\d$");
// if (regex.IsMatch(str))
// {
// sb.AppendLine();
// }
// sb.AppendLine(str);
// }
// MessageBox.Show(sb.ToString(), "更新日志", MessageBoxButton.OK, MessageBoxImage.Information);
// Properties.Settings.Default.Notification = false;
// Properties.Settings.Default.Save();
// }
//}
private void UpdateCheck ( )
{
// Uncomment following line to run update process without admin privileges.
AutoUpdater . RunUpdateAsAdmin = false ;
// Uncomment following line if you want to open download page instead of downloading update file when user click on download button.
// AutoUpdater.OpenDownloadPage = true;
// Uncomment following lines if you don't want user to select remind later time in AutoUpdater notification window.
//AutoUpdater.LetUserSelectRemindLater = false;
//AutoUpdater.RemindLaterTimeSpan = RemindLaterFormat.Days;
//AutoUpdater.RemindLaterAt = 2;
// Uncomment following line if you don't want to show Skip button.
// AutoUpdater.ShowSkipButton = false;
// Uncomment following line if you don't want to show Remind Later button.
//AutoUpdater.ShowRemindLaterButton = false;
// Uncomment following line to show custom application title in AutoUpdater notification window.
AutoUpdater . AppTitle = "SZMEDI工具 更新" ;
// Uncomment following line if you want to show errors.
AutoUpdater . ReportErrors = true ;
// Uncomment following lines if you want to handle how your application will exit when application finishes downloading the update.
//AutoUpdater.ApplicationExitEvent += () =>
//{
// Title = @"关闭程序中...";
// Thread.Sleep(5000);
// Application.Current.Shutdown();
//};
// Uncomment following lines to handle update logic yourself.
//AutoUpdater.ParseUpdateInfoEvent += args =>
//{
// dynamic json = JsonConvert.DeserializeObject(args.RemoteData);
// args.UpdateInfo = new UpdateInfoEventArgs
// {
// CurrentVersion = json.version,
// ChangelogURL = json.changelog,
// DownloadURL = json.url,
// Mandatory =
// new Mandatory
// {
// Value = json.mandatory.value,
// UpdateMode = json.mandatory.mode,
// MinimumVersion = json.mandatory.minVersion
// },
// CheckSum =
// new CheckSum { Value = json.checksum.value, HashingAlgorithm = json.checksum.hashingAlgorithm }
// };
//};
AutoUpdater . CheckForUpdateEvent + = args = >
{
switch ( args . Error )
{
case null when args . IsUpdateAvailable :
{
// var loc = typeof(Properties.Settings).Assembly.Location;
var collection = Properties . Settings . Default . UpdateNotes ;
var sb = new StringBuilder ( ) ;
foreach ( var str in collection )
{
sb . AppendLine ( str ) ;
}
var messageBoxResult = args . Mandatory . Value
? MessageBox . Show (
$"有新的版本 {args.CurrentVersion} 可用。正在使用的版本:{args.InstalledVersion} 必须进行更新。更新内容:\n\r{sb}" ,
"SZMEDI工具 更新" ,
MessageBoxButton . OK ,
MessageBoxImage . Information
)
: MessageBox . Show (
$"有新的版本 {args.CurrentVersion} 可用。你正在使用的版本:{args.InstalledVersion}。是否想要退出Revit进行更新程序? 更新内容: \n\r{sb}" ,
"SZMEDI工具 更新" ,
MessageBoxButton . YesNo ,
MessageBoxImage . Question
) ;
//显示标准的更新窗口
//AutoUpdater.ShowUpdateForm(args);
if ( messageBoxResult . Equals ( MessageBoxResult . OK ) | | messageBoxResult . Equals ( MessageBoxResult . Yes ) )
{
try
{
if ( AutoUpdater . DownloadUpdate ( args ) )
{
Process . GetCurrentProcess ( ) . Kill ( ) ;
//Application.Current.Shutdown();
}
}
catch ( Exception exception )
{
MessageBox . Show ( exception . Message , exception . GetType ( ) . ToString ( ) , MessageBoxButton . OK , MessageBoxImage . Error ) ;
}
}
break ;
}
case null :
//MessageBox.Show(@"无更新可用,请稍后再试", @"无更新可用",
// MessageBoxButton.OK, MessageBoxImage.Information);
break ;
case WebException :
//MessageBox.Show("更新服务器出现问题。请检查网络连接,稍后再试。", "更新检查失败", MessageBoxButton.OK, MessageBoxImage.Error);
break ;
default :
//MessageBox.Show(args.Error.Message,
// args.Error.GetType().ToString(), MessageBoxButton.OK,
// MessageBoxImage.Error);
break ;
}
} ;
// Uncomment following lines if you want to use XML and update file served only through Proxy.
// var proxy = new WebProxy("local-proxy-IP:8080", true) {Credentials = new NetworkCredential("domain\\user", "password")};
// AutoUpdater.Proxy = proxy;
// Uncomment following lines to periodically check for updates.
// var timer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(2) };
// timer.Tick += delegate { AutoUpdater.Start("http://rbsoft.org/updates/AutoUpdaterTest.xml"); };
// timer.Start();
// Uncomment following lines to provide basic authentication credentials needed to access update resources.
// var basicAuthentication = new BasicAuthentication("myUserName", "myPassword");
// AutoUpdater.BasicAuthXML = AutoUpdater.BasicAuthDownload = AutoUpdater.BasicAuthChangeLog = basicAuthentication;
// Uncomment following lines to enable forced updates.
// AutoUpdater.Mandatory = true;
// AutoUpdater.UpdateMode = Mode.Forced;
// Uncomment following line to change AutoUpdater notification window size.
//AutoUpdater.UpdateFormSize = new System.Drawing.Size(800, 600);
// Uncomment following line if you your XML file can only be accessed through FTP.
//AutoUpdater.Start($"{Properties.Settings.Default.FTPServerIP}Updates/AutoUpdater.xml", new NetworkCredential(), Assembly.GetExecutingAssembly());
AutoUpdater . Start ( $"{Properties.Settings.Default.FTPServerIP}Updates/AutoUpdater.xml" , new NetworkCredential ( ) , Assembly . GetExecutingAssembly ( ) ) ;
// Uncomment following lines if you want to persist Remind Later and Skip values in a json file instead of registry.
// string jsonPath = Path.Combine(Environment.CurrentDirectory, "settings.json");
// AutoUpdater.PersistenceProvider = new JsonFilePersistenceProvider(jsonPath);
// Uncomment following lines if you want to change the update zip extraction path. This only works when you use zip file as an update file.
//DirectoryInfo currentDirectory = new(Environment.CurrentDirectory);
//if (currentDirectory.Parent != null)
//{
// AutoUpdater.InstallationPath = currentDirectory.Parent.FullName;
//}
// Uncomment following line if you want to check for update synchronously.
// AutoUpdater.Synchronous = true;
// Uncomment following line if you want to assign installed version manually and don't want to rely on the library to determine the installed version from assembly.
// AutoUpdater.InstalledVersion = new Version("2.0.0.1");
// Uncomment following line if you want to clear application directory before update zip is extracted. This only works when you use zip file as an update file.
// AutoUpdater.ClearAppDirectory = true;
// Uncomment following line if you want to execute different executable after the update. This only works when you use zip file as an update file.
//AutoUpdater.ExecutablePath = "bin/AutoUpdaterTest.exe";
// Uncomment following line to set this window as owner of the all dialogs initiated by AutoUpdater.
AutoUpdater . SetOwner ( System . Diagnostics . Process . GetCurrentProcess ( ) . MainWindowHandle ) ;
// Uncomment following line to set TopMost to true for all updater dialogs. It is necessary to do this if TopMost is set to true in your form or window.
AutoUpdater . TopMost = true ;
// Uncomment following line to change the Icon shown on the updater dialog.
//AutoUpdater.Icon = Properties.Resources.Icon;
}
internal void MEPApp ( RibbonPanel ribbonPanel )
{
PushButtonData createStandMepCurvePbd =
new ( nameof ( StandMepCurveCmd ) , "创建立管" , AddInPath , typeof ( StandMepCurveCmd ) . FullName )
{
Image = Resources . stand_mepcurve_16px . ToBitmapSource ( ) ,
ToolTip = "通过点选,快速创建立管" ,
AvailabilityClassName = typeof ( EnableOnPlan ) . FullName
} ;
PushButtonData bloomConnectorPbd =
new ( nameof ( BloomConnectorCmd ) , "引出管线" , AddInPath , typeof ( BloomConnectorCmd ) . FullName )
{
Image = Resources . bloom_16px . ToBitmapSource ( ) ,
ToolTip = "从连接件生成默认管线"
} ;
PushButtonData anyConnectPbd =
new ( nameof ( AnyConnectCmd ) , "任意连接" , AddInPath , typeof ( AnyConnectCmd ) . FullName )
{
Image = Resources . any_connect_16px . ToBitmapSource ( ) ,
ToolTip = "选择任意的管线,进行管线连接" ,
LongDescription = "选择任意的2、3、4根管线, 根据其位置关系, 对管线进行连接"
} ;
PushButtonData moveConnectPbd =
new ( nameof ( MoveConnectCmd ) , "移动连接" , AddInPath , typeof ( MoveConnectCmd ) . FullName )
{
Image = Resources . move_connect_16px . ToBitmapSource ( ) ,
ToolTip = "根据最近距离的未连接的连接件,将其连接或角度过大则对齐连接"
} ;
PushButtonData breakMepCurvePbd =
new ( nameof ( BreakMEPCurveCmd ) , "管线打断" , AddInPath , typeof ( BreakMEPCurveCmd ) . FullName )
{
Image = Resources . break_mepcurve_16px . ToBitmapSource ( ) ,
ToolTip = "选择点进行对管线进行打断"
} ;
PushButtonData disConnectPbd =
new ( nameof ( DisconnectCmd ) , "断开连接" , AddInPath , typeof ( DisconnectCmd ) . FullName )
{
Image = Resources . disconnect_16px . ToBitmapSource ( ) ,
ToolTip = "选择已连接的图元,断开其连接"
} ;
PushButtonData flipWorkplanePbd =
new ( nameof ( FlipWorkplaneCmd ) , "翻转工作平面" , AddInPath , typeof ( FlipWorkplaneCmd ) . FullName )
{
Image = Resources . FlipWorkplane_16px . ToBitmapSource ( ) ,
LargeImage = Resources . FlipWorkplane_32px . ToBitmapSource ( ) ,
ToolTip = "将可以翻转工作平面的族实例,翻转其工作平面"
} ;
PushButtonData rotateInstancePbd =
new ( nameof ( RotateInstanceCmd ) , "旋转实例" , AddInPath , typeof ( RotateInstanceCmd ) . FullName )
{
Image = Resources . RotateInstance_16px . ToBitmapSource ( ) ,
LargeImage = Resources . RotateInstance_32px . ToBitmapSource ( ) ,
ToolTip = "将族实例根据已连接的情况进行旋转,比如管件"
} ;
PushButtonData viewSectionPbd =
new ( nameof ( QuickViewSectionCmd ) , "快速剖面" , AddInPath , typeof ( QuickViewSectionCmd ) . FullName )
{
LargeImage = Resources . ViewSection_32px . ToBitmapSource ( ) ,
Image = Resources . ViewSection_16px . ToBitmapSource ( ) ,
ToolTip = "对基于线的实例,如墙、梁,管线等进行快速剖面视图" ,
} ;
PushButtonData addinsulationPbd =
new ( nameof ( AddInsulationCmd ) , "保温层" , AddInPath , typeof ( AddInsulationCmd ) . FullName )
{
LargeImage = Resources . AddInsulation_32px . ToBitmapSource ( ) ,
Image = Resources . AddInsulation_16px . ToBitmapSource ( ) ,
ToolTip = "对水管和风管添加保温层" ,
} ;
PushButtonData mepCurveSignPbd =
new ( nameof ( MEPCurveSignCmd ) , "管线标识" , AddInPath , typeof ( MEPCurveSignCmd ) . FullName )
{
Image = Resources . MEPCurve_Sign_16px . ToBitmapSource ( ) ,
LargeImage = Resources . MEPCurve_Sign_32px . ToBitmapSource ( ) ,
ToolTip = "在管线面上添加管线标识"
} ;
PushButtonData arrangeMEPPbd =
new ( nameof ( ArrangeMEPCurveCmd ) , "管线排布" , AddInPath , typeof ( ArrangeMEPCurveCmd ) . FullName )
{
LargeImage = Resources . ArrangeMep_32px . ToBitmapSource ( ) ,
Image = Resources . ArrangeMep_16px . ToBitmapSource ( ) ,
ToolTip = "根据相对位置排布管线" ,
} ;
PushButtonData clashResolvePbd =
new ( nameof ( ClashResolveCmd ) , "碰撞处理" , AddInPath , typeof ( ClashResolveCmd ) . FullName )
{
LargeImage = Resources . clash_resolve_32px . ToBitmapSource ( ) ,
Image = Resources . clash_resolve_16px . ToBitmapSource ( ) ,
ToolTip = "对碰撞的管线进行避让处理" ,
} ;
PushButtonData clashReportPbd =
new ( nameof ( ClashReportCmd ) , "碰撞报告" , AddInPath , typeof ( ClashReportCmd ) . FullName )
{
LargeImage = Resources . clash_report_32px . ToBitmapSource ( ) ,
Image = Resources . clash_report_16px . ToBitmapSource ( ) ,
ToolTip = "根据Revit自带的报告, 快速定位问题构件"
} ;
ribbonPanel . AddStackedItems ( createStandMepCurvePbd , bloomConnectorPbd , anyConnectPbd ) ;
ribbonPanel . AddStackedItems ( moveConnectPbd , breakMepCurvePbd , disConnectPbd ) ;
ribbonPanel . AddSplitButton (
new ( "机电修改工具" , "机电修改工具" ) ,
arrangeMEPPbd ,
mepCurveSignPbd ,
rotateInstancePbd ,
flipWorkplanePbd ,
addinsulationPbd ) ;
ribbonPanel . AddStackedItems ( viewSectionPbd , clashResolvePbd , clashReportPbd ) ;
//ribbonPanel.AddSplitButton(splitBtn, clashResolvePbd, clashReportPbd);
}
internal static void UiApp_ViewActivated ( object sender , Autodesk . Revit . UI . Events . ViewActivatedEventArgs e )
{
if ( sender is not UIApplication uiApp )
{
return ;
}
var uidoc = uiApp . ActiveUIDocument ;
var doc = uidoc . Document ;
var elemIdsSelected = uidoc . Selection . GetElementIds ( ) ;
if ( uidoc . Selection . GetElementIds ( ) . Count ! = 1 )
{
return ;
}
var elem = doc . GetElement ( elemIdsSelected . FirstOrDefault ( ) ) ;
var b = IsVisible ( e . CurrentActiveView . Id , elem ) ;
if ( ! b )
{
return ;
}
var box = elem . get_BoundingBox ( uidoc . ActiveGraphicalView ) ;
var uiView = uidoc . GetOpenUIViews ( ) . FirstOrDefault ( v = > v . ViewId = = uidoc . ActiveGraphicalView . Id ) ;
uiView ! . ZoomAndCenterRectangle ( box . Min , box . Max ) ;
}
public void AnnotationApp ( RibbonPanel ribbonPanel )
{
PushButtonData dimensionView3dPbd =
new ( "三维轴网" , "三维轴网" , AddInPath , typeof ( DimensionView3dCmd ) . FullName )
{
Image = Resources . Grid3D_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Grid3D_32px . ToBitmapSource ( ) ,
ToolTip = "生成三维轴网并标注" ,
} ;
PushButtonData dimension2DTo3DPbd =
new ( "复制标注" , "复制标注" , AddInPath , typeof ( Dimension2DTo3DCmd ) . FullName )
{
Image = Resources . Copy2DTo3D_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Copy2DTo3D_32px . ToBitmapSource ( ) ,
ToolTip = "将平面标注复制到三维视图" ,
AvailabilityClassName = typeof ( EnableOnPlan ) . FullName
} ;
//PushButtonData dimensionElemPbd =
// new("元素标注", "元素标注", AddInPath, typeof(DimensionElemCmd).FullName)
// {
// Image = Resources.DimensionELement_16px.ToBitmapSource(),
// LargeImage = Resources.DimensionELement_32px.ToBitmapSource(),
// ToolTip = "对元素所有平行参考标注"
// };
PushButtonData dimensionBy2LinePbd =
new ( "双线标注" , "双线标注" , AddInPath , typeof ( DimensionBy2LineCmd ) . FullName )
{
Image = Resources . Dimmension2L_16px . ToBitmapSource ( ) ,
LargeImage = Resources . Dimmension2L_32px . ToBitmapSource ( ) ,
ToolTip = "选择任意两条平行的线进行标注"
} ;
PushButtonData mergeDimensionsPbd =
new ( "合并尺寸标注" , "合并标注" , AddInPath , typeof ( MergeDimensionsCmd ) . FullName )
{
Image = Resources . MergeDim_16px . ToBitmapSource ( ) ,
LargeImage = Resources . MergeDim_32px . ToBitmapSource ( ) ,
ToolTip = "合并尺寸标注"
} ;
PushButtonData splitDimensionsPbd =
new ( "拆分尺寸标注" , "拆分标注" , AddInPath , typeof ( SplitDimensionsCmd ) . FullName )
{
Image = Resources . SeparateDim_16px . ToBitmapSource ( ) ,
LargeImage = Resources . SeparateDim_32px . ToBitmapSource ( ) ,
ToolTip = "拆分尺寸标注"
} ;
//PushButtonData dimensionByPointLinePbd =
// new PushButtonData("点线标注", "点线标注", AddInPath, typeof(DimensionPointLineCmd).FullName)
// {
// ToolTip = "选择点线进行标注"
// };
ribbonPanel . AddStackedItems ( dimensionView3dPbd , dimension2DTo3DPbd , dimensionBy2LinePbd ) ;
//ribbonPanel.AddStackedItems(dimensionElemPbd, dimensionBy2LinePbd);
ribbonPanel . AddStackedItems ( mergeDimensionsPbd , splitDimensionsPbd ) ;
//ribbonPanel.AddStackedItems(dimensionView3dPbd, dimension2DTo3DPbd);
//ribbonPanel.AddStackedItems(dimensionElemPbd, dimensionBy2LinePbd);
}
public void DisplayApp ( RibbonPanel ribbonPanel )
{
PushButtonData p1 =
new ( "替换外观" , "替换外观" , AddInPath , typeof ( OverrideElementsCmd ) . FullName )
{
Image = Resources . Override_16px . ToBitmapSource ( ) ,
ToolTip = "替换当前视图框选元素的外观为半透明绿色" ,
AvailabilityClassName = typeof ( EnableOnView3d ) . FullName
} ;
PushButtonData p2 =
new ( "恢复外观" , "恢复外观" , AddInPath , typeof ( ResetColorOverrideCmd ) . FullName )
{
Image = Resources . Reset_16px . ToBitmapSource ( ) ,
ToolTip = "恢复当前视图框选元素的默认外观" ,
AvailabilityClassName = typeof ( EnableOnView3d ) . FullName
} ;
ribbonPanel . AddStackedItems ( p1 , p2 ) ;
}
public void InsertQuickAccessAndHidePanel ( )
{
var tab = RibbonControl . FindTab ( TabName ) ;
if ( tab ! = null & & addInManagerPanel ! = null )
{
var checklistButton = addInManagerPanel . Source . Items . FirstOrDefault ( ) ;
ComponentManager . QuickAccessToolBar . AddStandardItem ( checklistButton ) ;
//移除面板
tab . Panels . Remove ( addInManagerPanel ) ;
//if (FAIRTab.Panels.Count == 0) FAIRTab.IsVisible = false;
}
}
2025-12-23 21:37:02 +08:00
private static void CreateLogger ( )
{
AppDomain . CurrentDomain . UnhandledException + = ( _ , args ) = >
{
var e = ( Exception ) args . ExceptionObject ;
LogAssists . WriteLog ( e . Message ) ;
} ;
}
2025-09-16 16:06:41 +08:00
public override void OnStartup ( )
{
2025-12-23 21:37:02 +08:00
CreateLogger ( ) ;
2025-09-16 16:06:41 +08:00
UpdateCheck ( ) ;
zoomElementHandler = new ( ) ;
saveHandler = new ( ) ;
const BindingFlags flag = BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . InvokeMethod ;
uiapp = ( UIApplication ) Application . GetType ( ) . InvokeMember ( "getUIApplication" , flag , Type . DefaultBinder , Application , null ) ;
GlobalVariables . UIApplication = uiapp ;
CreateModifyUI ( ) ;
CreateRibbonUI ( Application ) ;
RegisterDockPaneAndEvent ( Application ) ;
//if (ZoomRBGroup.Current.Equals(ZoomRBGroup.GetItems()[0]))
//{
// uiapp.ViewActivated -= UiApp_ViewActivated;
// uiapp.ViewActivated += UiApp_ViewActivated;
//}
//else
//{
// uiapp.ViewActivated -= UiApp_ViewActivated;
//}
Application . ControlledApplication . ApplicationInitialized + = ControlledApplication_ApplicationInitialized ;
//族文件隐藏插件
//Application.ViewActivating += Application_ViewActivating;
if ( Properties . Settings . Default . AutoSave )
{
GlobalVariables . Timer . Interval = Properties . Settings . Default . AutoSaveIntervalTime * 60 * 1000 ;
GlobalVariables . Timer . Elapsed - = OnTimedEvent ;
GlobalVariables . Timer . Elapsed + = OnTimedEvent ;
GlobalVariables . Timer . Start ( ) ;
}
//var collection = new List<string>
//{
// "System.Runtime.CompilerServices.Unsafe",
// "System.Memory",
// "System.Numerics.Vectors",
//};
//foreach (var item in collection)
//{
// string services = Path.Combine(GlobalVariables.DirAssembly, $"{item}.dll");
// Assembly.LoadFrom(services);
//}
}
2025-12-23 21:37:02 +08:00
public override void OnShutdown ( )
{
Application . ControlledApplication . ApplicationInitialized - = ControlledApplication_ApplicationInitialized ;
GlobalVariables . Timer . Stop ( ) ;
}
2025-09-16 16:06:41 +08:00
/// <summary>
/// 上传使用数据
/// </summary>
public void UploadToFTP ( string filePath )
{
var ftpUrl = $"ftp://{Properties.Settings.Default.FTPServerIP}/SzmediTools/Utilization.txt" ;
var request = ( FtpWebRequest ) WebRequest . Create ( ftpUrl ) ;
request . Method = WebRequestMethods . Ftp . UploadFile ;
request . Credentials = new NetworkCredential ( ) ;
request . UsePassive = true ;
request . UseBinary = true ;
request . KeepAlive = false ;
using ( var fs = new FileStream ( filePath , FileMode . Open ) )
using ( var ftpStream = request . GetRequestStream ( ) )
{
var buffer = new byte [ 1024 ] ;
int bytesRead ;
while ( ( bytesRead = fs . Read ( buffer , 0 , buffer . Length ) ) > 0 )
{
ftpStream . Write ( buffer , 0 , bytesRead ) ;
}
}
}
public RibbonControl RibbonControl = > ComponentManager . Ribbon ;
}