Files
MsAddIns/RingPlacementAddin/CellHelper.cs
2026-02-28 21:01:57 +08:00

254 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
}
}
}