Files
MsAddIns/RingPlacementAddin/CellHelper.cs

254 lines
12 KiB
C#
Raw Normal View History

2026-02-28 21:01:57 +08:00
using System.Collections.Generic;
using System.Linq;
using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.DgnEC;
using Bentley.DgnPlatformNET.Elements;
using Bentley.ECObjects.Instance;
using Bentley.GeometryNET;
using Bentley.MstnPlatformNET;
using Bentley.MstnPlatformNET.InteropServices;
namespace RingPlacementAddin
{
public class CellHelper
{
/// <summary>
/// 创建单元
/// </summary>
/// <param name="cellName"></param>
/// <param name="listElems">创建单元组成元素集</param>
public static CellHeaderElement CreateCell(string cellName, List<Element> listElems)
{
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得创建文本元素的模型空间
DPoint3d ptOri = new();//设置单元放置位置
DMatrix3d rMatrix = DMatrix3d.Identity;//设置变换矩阵
CellHeaderElement cellHeaderEle = new(dgnModel, cellName, ptOri, rMatrix, listElems);//创建单元
cellHeaderEle.AddToModel();//将单元写入模型空间
return cellHeaderEle;
}
/// <summary>
/// 创建共享单元
/// </summary>
/// <param name="cellName"></param>
/// <param name="elements">子元素集</param>
public static SharedCellElement CreateSharedCell(string cellName, params Element[] elements)
{
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得创建文本元素的模型空间
SharedCellDefinitionElement sharedCellDefinition = new(dgnModel, cellName);//创建共享单元定义元素
foreach (var elem in elements)
{
sharedCellDefinition.AddChildElement(elem);//将构成元素添加到共享单元定义元素中
}
sharedCellDefinition.AddChildComplete();//添加构件完成
sharedCellDefinition.AddToModel();//将共享单元定义元素写入模型
DPoint3d origin = DPoint3d.Zero;//设置插入点坐标
DPoint3d scale = new(1, 1, 1);//设置缩放比例
SharedCellElement sharedCell = new(dgnModel, null, cellName, origin, DMatrix3d.Identity, scale);//创建共享单元元素
sharedCell.SetDefinitionId(sharedCellDefinition.ElementId);//指定该共享单元的定义元素
TransformInfo transInfo = new(DTransform3d.Identity);//创建变换信息
sharedCell.ApplyTransform(transInfo);//对共享单元元素应用变换信息
sharedCell.AddToModel();//将共享单元添加到模型中
return sharedCell;
}
public static void AttachCellLib(string CellLibraryName)
{
Bentley.Interop.MicroStationDGN.Application msApp = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp;
msApp.AttachCellLibrary(CellLibraryName);
//DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得创建文本元素的模型空间
//var dgnFile = Session.Instance.GetActiveDgnFile();
//dgnModel.FindApplicationData(dgnFile);
}
public static void DetachCellLibs()
{
Bentley.Interop.MicroStationDGN.Application msApp = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp;
msApp.DetachCellLibrary();
//DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得创建文本元素的模型空间
//var dgnFile = Session.Instance.GetActiveDgnFile();
//dgnModel.FindApplicationData(dgnFile);
}
/// <summary>
/// 确定单元模型
/// </summary>
/// <param name="name">单元名称</param>
/// <returns></returns>
private static DgnModel LocateCellModel(string name)
{
var opts = CellLibraryOptions.Include3d | CellLibraryOptions.IncludeAllLibraries | CellLibraryOptions.IncludeParametric;
var libs = new CellLibraryCollection(opts);
DgnModel cellModel = null;
foreach (var lib in libs)
{
MessageCenter.Instance.ShowInfoMessage(lib.Name, lib.Name, false);
if (name.Equals(lib.Name))
{
cellModel = lib.File.LoadRootModelById(out StatusInt status, lib.File.FindModelIdByName(lib.Name), true, false, true);
break;
}
}
return cellModel;
}
/// <summary>
/// 获取连接的单元库
/// </summary>
/// <returns></returns>
public static CellLibraryCollection GetCellLibs()
{
return new CellLibraryCollection(CellLibraryOptions.DefaultAll);
}
/// <summary>
/// 变换的合法性
/// </summary>
/// <param name="trans"></param>
public static void Legal(DTransform3d trans)
{
if (!trans.Matrix.IsRigid())//刚性矩阵,旋转 + 平移,行列式为 +1排除镜像。所有缩放因子为 1无拉伸/压缩)。
{
MessageCenter.Instance.ShowErrorMessage("变换矩阵非刚性", null, true);//输出参数化单元定义声明失败的提示
return;
}
if (!trans.Matrix.IsOrthogonal())//正交矩阵,用于旋转,行列式为 ±1+1 是旋转,-1 是镜像)。
{
MessageCenter.Instance.ShowErrorMessage("变换矩阵非正交", null, true);//输出参数化单元定义声明失败的提示
return;
}
if (!trans.Matrix.IsDiagonal())//对角矩阵,缩放
{
MessageCenter.Instance.ShowErrorMessage("变换矩阵非正交", null, true);//输出参数化单元定义声明失败的提示
return;
}
}
/// <summary>
/// 导入参数化单元
/// </summary>
/// <param name="cellFilePath"></param>
/// <param name="cellName"></param>
public static ParametricCellElement ImportParametricCellElement(string cellFilePath, string cellName, DTransform3d trans, Dictionary<string, object> parametersDict = null)
{
DgnDocument document = DgnDocument.CreateForLocalFile(cellFilePath);//根据路径获取单元库文件
DgnFileOwner owner = DgnFile.Create(document, DgnFileOpenMode.ReadOnly);//声明可读取文件信息的DgnFile对象
DgnFile cellFile = owner.DgnFile;//获得读取文件信息的对象
cellFile.LoadDgnFile(out StatusInt fileLoadStatus);//读取文件信息
if (fileLoadStatus == StatusInt.Error)//若读取失败则返回
{
return null;
}
ModelId id = cellFile.FindModelIdByName(cellName);//根据单元名称获取对应单元的模型ID
DgnModel cellModel = cellFile.LoadRootModelById(out StatusInt modelLoadStatus, id);//根据模型ID获取对应的模型空间
if (modelLoadStatus == StatusInt.Error)// 若读取失败则返回
{
return null;
}
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获取当前激活的文件
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获取当前激活的模型
ParametricCellDefinitionElement pcDef = ParametricCellDefinitionElement.FindByName(cellName, dgnFile);//根据名称在文件中获取对应的参数化定义元素
if (null == pcDef)//判断是否存在指定的参数化模型定义
{
DgnComponentDefinitionHandler hdlr = DgnComponentDefinitionHandler.GetForModel(cellModel);//获得模型中的定义句柄
ParameterStatus status = hdlr.DefinitionModelHandler.CreateCellDefinition(dgnFile);//声明单元定义
if (ParameterStatus.Success == status)//判断是否声明成功
{
pcDef = ParametricCellDefinitionElement.FindByName(cellName, dgnFile);//根据名称在文件中获取对应的参数化定义元素
}
else
{
MessageCenter.Instance.ShowErrorMessage("创建单元定义错误", null, true);//输出参数化单元定义声明失败的提示
return null;
}
}
if (pcDef != null)//判断参数化单元定义是否成功声明
{
ParametricCellElement pc = ParametricCellElement.Create(pcDef, null, dgnModel);//使用参数化定义声明参数化元素
IDgnECInstance inst = pc.Parameters as IDgnECInstance;
if (parametersDict != null)
{
foreach (var paramPair in parametersDict)
{
var key = paramPair.Key;
var value = paramPair.Value;
IECArrayValue arr = inst.GetPropertyValue("ParameterValuesContainer") as IECArrayValue;
foreach (IECStructValue entry in arr)
{
if (entry.Any(prop => prop.TryGetStringValue(out var str) && str == paramPair.Key))
{
entry.SetValue("Adhoc_Value", value);
}
}
}
}
inst.ScheduleChanges(pc);
//DTransform3d trans = DTransform3d.Identity;//声明变换几何
TransformInfo transInfo = new(trans);//声明变换信息
pc.ApplyTransform(transInfo);//对参数化单元进行变换
pc.AddToModel();//将参数化单元元素写入模型
return pc;
}
return null;
}
/// <summary>
/// 参数化单元名称
/// </summary>
/// <param name="pcName"></param>
public static void CreateParametricCell(string pcName, DTransform3d trans, Dictionary<string, object> parametersDict = null)
{
//const string setName = "Standard";
var dgnFile = Session.Instance.GetActiveDgnFile();
var dgnModel = Session.Instance.GetActiveDgnModel();
var pcDef = ParametricCellDefinitionElement.FindByName(pcName, dgnFile);
if (null == pcDef) //Not find cell def in active design file
{
var cellModel = LocateCellModel(pcName);
if (null == cellModel)
{
MessageCenter.Instance.ShowInfoMessage("未找到单元", null, true);
return;
}
var hdlr = DgnComponentDefinitionHandler.GetForModel(cellModel);
var status = hdlr.DefinitionModelHandler.CreateCellDefinition(dgnFile);
if (ParameterStatus.Success == status)
pcDef = ParametricCellDefinitionElement.FindByName(pcName, dgnFile);
else
{
MessageCenter.Instance.ShowInfoMessage("创建单元定义错误", null, true);
return;
}
}
//IECStructArrayValue, IECArrayValue, IECStructValue, IECPropertyValue
//Utilities.ComApp.CreateCellElement2(pcName,ref )
var pc = ParametricCellElement.Create(pcDef, /*setName*/"", dgnModel);
IDgnECInstance inst = pc.Parameters as IDgnECInstance;
if (parametersDict != null)
{
foreach (var paramPair in parametersDict)
{
var key = paramPair.Key;
var value = paramPair.Value;
IECArrayValue arr = inst.GetPropertyValue("ParameterValuesContainer") as IECArrayValue;
foreach (IECStructValue entry in arr)
{
if (entry.Any(prop => prop.TryGetStringValue(out var str) && str == paramPair.Key))
{
entry.SetValue("Adhoc_Value", value);
}
}
}
}
inst.ScheduleChanges(pc);
//DTransform3d trans = DTransform3d.Identity;
//trans.Translation = new DVector3d(1000, 2000, 3000); //UOR unit
TransformInfo transInfo = new(trans);
pc.ApplyTransform(transInfo);
pc.AddToModel();
}
}
}