第九期视频回放
第九期代码及课件下载地址
第九期直播内容文字版
本次直播内容主要是对实际生产过程中经常出现的需求进行案例的介绍。从内容上分,主要涉及两个部分,分别为:出图阶段的表格,图纸生成案例与事件驱动的参数化建模案例。
图1 本期内容一览
出图相关案例
针对目前的设计生产模式来说,最终工程信息都会以图纸的形式进行表达。作为BIM模型,其中拥有海量的工程信息,但是如何将模型中的信息归类,快速整合并输出为符合公司出图标准的图纸或表格,也是目前BIM技术短时间无法取代传统CAD绘制出图模式的一大原因。这里,我们给大家分别介绍用于生成符合公司要求图表的工具Demo和绘制构件后自动生成图纸的工具Demo。
表格生成工具
该工具主要用于从模型中提取生成表格所需的信息,并自动生成表格。对于表格本身,若表格较为简单,可使用MicroStation内置的表格,若内置表格样式无法满足出图的需要,那么可以采用线与文字配合生成的方式,创建符合公司出图标准的图表,同时,表格数据还可输出为Excel文件的格式,提供多样形式的数据输出。
需求说明:
使用工具对构件进行筛选,选择完毕后从选择的元素中提取生成图表的有效信息生成图表,同时也可使用表格信息生成对应的Excel文件。
要求:
选择元素需要具有批量选择(框选/划选),单项选择(按住Ctrl点选)的正选/反选功能,完成选择后需要在界面显示生成图表的预览图,具有生成默认图表与自定义图表的功能,并可输出为Excel格式的表格文件。
分析:
该工具大致可分为三个阶段:选择模型中元素阶段,界面中预览图表与参数设置阶段,放置图表阶段。其中第一个与最后一个阶段涉及到交互式工具的使用,而中间的阶段涉及到界面的交互。
图2 表格生成工具流程图
using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.Elements;
using Bentley.GeometryNET;
using Bentley.MstnPlatformNET;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExampleofCase.UI;
namespace ExampleofCase.DataAnalysisTool
{
class DataAnalysisCommand : DgnElementSetTool
{
public static List<Element> m_elems;//声明元素列表
public DataAnalysisCommand(int toolId, int prompt) : base(toolId, prompt)//继承基类的构造函数
{
}
public static void InstallNewInstance()//该命令的入口函数
{
DataAnalysisCommand primitiveTool = new DataAnalysisCommand(0, 0);//创建实例
primitiveTool.InstallTool();//加载工具
}
public override StatusInt OnElementModify(Element element)
{
return StatusInt.Error;
}
protected override void OnRestartTool()
{
InstallNewInstance();
}
protected override void OnPostInstall()//工具激活后执行
{
string tips = "Please select elements to be analyzed:";//设置提示语
NotificationManager.OutputPrompt(tips);//将提示语输出到提示框中
m_elems = new List<Element>();//定义元素列表
}
protected override bool WantAdditionalLocate(DgnButtonEvent ev)//判断当前是否需要拾取元素
{
if (ev == null)//若没有选择到元素
{
return true;
}
if (ev.IsControlKey)//若检测到按动Ctrl行为
{
return true;
}
if (ElementAgenda.GetCount() == 0)//若选择集中没有元素
{
return true;
}
return false;
}
protected override bool OnResetButton(DgnButtonEvent ev)//重置键(默认右键)点击时触发
{
ExitTool();//退出交互式工具
return true;
}
protected override UsesDragSelect AllowDragSelect()//判断是否要启用框选或者划选
{
return UsesDragSelect.Box;//使用框选选择元素
}
protected override bool NeedAcceptPoint()//判断是否需要用户再点击左键才开始处理元素
{
return false;
}
protected override bool OnModifyComplete(DgnButtonEvent ev)//修改完毕,对选择集中的元素进行处理
{
m_elems.Clear();//清空列表项
for (uint i=0;i<ElementAgenda.GetCount();i++)//遍历选择集中的元素
{
m_elems.Add(ElementAgenda.GetEntry(i));//将选择集中的元素添加到列表中
}
if(m_elems.Count==0)//判断列表中元素个数
{
MessageCenter.Instance.ShowInfoMessage("No elements selected", "No elements selected", true);//输出未选择元素的提示
return base.OnModifyComplete(ev);//返回并调用基类方法
}
MessageCenter.Instance.ShowInfoMessage("Element selection succeeded", "Element selection succeeded", false);//输出选中元素成功的提示
DataFilterMenu menu = new DataFilterMenu();//声明界面
menu.AttachToToolSettings(csAddins.MyAddin.Addin);//将界面添加到工具框中
menu.Show();//显示界面
return base.OnModifyComplete(ev);//返回并调用基类方法
}
}
class ElementPlacementCommand : DgnElementSetTool
{
private const int WIDTH = 4000;//声明自定义图表的宽度
private const int HEIGHT = 2000;//声明自定义图表的高度
private List<Element> m_elems;//声明元素列表
private Element m_textTableElem;//声明用于创建自定义图表的元素
public ElementPlacementCommand(int toolId, int prompt) : base(toolId, prompt)//继承基类的构造函数
{
}
public static void InstallNewInstance()//该命令的入口函数
{
ElementPlacementCommand primitiveTool = new ElementPlacementCommand(0, 0);//创建实例
primitiveTool.InstallTool();//加载工具
}
public override StatusInt OnElementModify(Element element)
{
return StatusInt.Error;
}
protected override void OnRestartTool()
{
InstallNewInstance();
}
protected override void OnPostInstall()//工具激活后执行
{
string tips = "Please select elements to be analyzed:";//设置提示语
NotificationManager.OutputPrompt(tips);//将提示语输出到提示框中
m_elems = new List<Element>(DataFilterMenu.m_elems);//定义元素列表
DrawDataTable();
BeginDynamics();
}
protected override void OnDynamicFrame(DgnButtonEvent ev)
{
DynamicDrawElems(m_textTableElem, ev.Point);
}
protected override bool OnDataButton(DgnButtonEvent ev)
{
EndDynamics();
PlaceDataTable(m_textTableElem, ev.Point);
ExitTool();
return true;
}
protected override bool OnResetButton(DgnButtonEvent ev)
{
ExitTool();
return true;
}
private void DrawDataTable()
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的文件
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的模型空间
DgnTextStyle textStyle = DgnTextStyle.GetByName("Test1", dgnFile);//根据名称获得文字样式
if (null == textStyle)//判断是否成功获取同名文字样式
{
textStyle = new DgnTextStyle("Test1", dgnFile);//在文件中定义文字样式
DgnFont font = DgnFontManager.FindSystemFont("KaiTi", DgnFontFilterFlags.All);//获得名为"KaiTi"的字体
textStyle.SetFontProperty(TextStyleProperty.Font, font);//设置字体
textStyle.SetProperty(TextStyleProperty.Width, 1000D);//设置文字宽度
textStyle.SetProperty(TextStyleProperty.Height, 1000D);//设置文字高度
textStyle.Add(dgnFile);//将文字样式添加到文件中
}
ElementId textStyleId = textStyle.Id;//获得文字样式ID
if (DataFilterMenu.m_tableInfo.Item1==true)//通过元组参数判断
{
uint tableRow = 0;//设置用于表示图表行的变量
if(DataFilterMenu.m_tableInfo.Item2==0)//通过元组参数判断
{
tableRow = 6;//设置变量
}
else
{
tableRow = 2;//设置变量
}
TextTable textTable = TextTable.Create((uint)m_elems.Count+1, tableRow, textStyleId, 1000, dgnModel);//创建文字表
{
string nameDesc1 = "ID";//设置字符串
string nameDesc2 = "Desc";
if (DataFilterMenu.m_tableInfo.Item2 == 2)//通过元组参数判断
{
nameDesc1 = "Type";//设置字符串
nameDesc2 = "IsInvisible";
}
else if(DataFilterMenu.m_tableInfo.Item2 == 3)//通过元组参数判断
{
nameDesc1 = "IsValid";//设置字符串
nameDesc2 = "LevelId";
}
TableCellIndex index = new TableCellIndex(0, 0);//声明图表单元索引
TextTableCell tableCell = textTable.GetCell(index);//通过索引值获得文字表单元
tableCell.SetTextString(nameDesc1);//设置文字表单元名称
index = new TableCellIndex(0, 1);//定义图表单元索引
tableCell = textTable.GetCell(index);//通过索引值获得文字表单元
tableCell.SetTextString(nameDesc2);//设置文字表单元名称
if (DataFilterMenu.m_tableInfo.Item2 == 0)//通过元组参数判断
{
index = new TableCellIndex(0, 2);//声明图表单元索引
tableCell = textTable.GetCell(index);//通过索引值获得文字表单元
tableCell.SetTextString("Type");//设置文字表单元名称
index = new TableCellIndex(0, 3);
tableCell = textTable.GetCell(index);
tableCell.SetTextString("IsInvisible");
index = new TableCellIndex(0, 4);
tableCell = textTable.GetCell(index);
tableCell.SetTextString("IsValid");
index = new TableCellIndex(0, 5);
tableCell = textTable.GetCell(index);
tableCell.SetTextString("LevelId");
}
}
for (int i = 0; i < m_elems.Count; i++)//遍历元素列表
{
string nameDesc1 = m_elems[i].ElementId.ToString();//设置字符串
string nameDesc2 = m_elems[i].Description;
if (DataFilterMenu.m_tableInfo.Item2 == 2)//通过元组参数判断
{
nameDesc1 = m_elems[i].ElementType.ToString();//设置字符串
nameDesc2 = m_elems[i].IsInvisible.ToString();
}
else if (DataFilterMenu.m_tableInfo.Item2 == 3)
{
nameDesc1 = m_elems[i].IsValid.ToString();
nameDesc2 = m_elems[i].LevelId.ToString();
}
TableCellIndex index = new TableCellIndex((uint)i + 1, 0);//定义图表单元索引
TextTableCell tableCell = textTable.GetCell(index);//通过索引值获得文字表单元
tableCell.SetTextString(nameDesc1);//设置文字表单元名称
index = new TableCellIndex((uint)i + 1, 1);
tableCell = textTable.GetCell(index);
tableCell.SetTextString(nameDesc2);
if (DataFilterMenu.m_tableInfo.Item2 == 0)//通过元组参数判断
{
index = new TableCellIndex((uint)i + 1, 2);//定义图表单元索引
tableCell = textTable.GetCell(index);//通过索引值获得文字表单元
tableCell.SetTextString(m_elems[i].ElementType.ToString());//设置文字表单元名称
index = new TableCellIndex((uint)i + 1, 3);
tableCell = textTable.GetCell(index);
tableCell.SetTextString(m_elems[i].IsInvisible.ToString());
index = new TableCellIndex((uint)i + 1, 4);
tableCell = textTable.GetCell(index);
tableCell.SetTextString(m_elems[i].IsValid.ToString());
index = new TableCellIndex((uint)i + 1, 5);
tableCell = textTable.GetCell(index);
tableCell.SetTextString(m_elems[i].LevelId.ToString());
}
}
m_textTableElem = new TextTableElement(textTable);//声明文字表元素
}
else
{
IList<Element> subElems = new List<Element>();//声明元素列表
#region DrawCustomDataTable
int tableItems = 6;//设置Int变量
if(DataFilterMenu.m_tableInfo.Item2 != 0)//通过元组参数判断
{
tableItems = 2;//修改Int变量值
}
for(int i=0;i<tableItems+1;i++)//遍历
{
DPoint3d startPo = new DPoint3d(i*WIDTH,0);//设置图表行线起点
DPoint3d endPo = new DPoint3d(i * WIDTH, HEIGHT* m_elems.Count);//设置图表行线终点
DSegment3d segment = new DSegment3d(startPo,endPo);//声明几何直线
LineElement line = new LineElement(dgnModel, null, segment);//声明线元素
subElems.Add(line);//将线元素添加到列表中
}
for (int i = 0; i < m_elems.Count+1; i++)//遍历
{
DPoint3d startPo = new DPoint3d(0, i*HEIGHT);//设置图表列线起点
DPoint3d endPo = new DPoint3d(tableItems*WIDTH, i * HEIGHT);//设置图表列线终点
DSegment3d segment = new DSegment3d(startPo, endPo);//声明几何直线
LineElement line = new LineElement(dgnModel, null, segment);//声明线元素
subElems.Add(line);//将线元素添加到列表中
}
#endregion
#region InsertDataToDataTable
for (int i = 0; i < tableItems; i++)//遍历
{
for (int j = 0; j < m_elems.Count; j++)//遍历
{
DPoint3d insertPo = new DPoint3d(i*WIDTH,(1+j)*HEIGHT);//设置文字插入点
TextBlockProperties txtBlockProp = new TextBlockProperties(dgnModel);//定义文本属性
txtBlockProp.IsViewIndependent = false;//设置文本非独立于视图
ParagraphProperties paraProp = new ParagraphProperties(dgnModel);//定义段落属性
RunProperties runProp = new RunProperties(textStyle, dgnModel);//定义运行属性
TextBlock txtBlock = new TextBlock(txtBlockProp, paraProp, runProp, dgnModel);//定义文本块
if (DataFilterMenu.m_tableInfo.Item2 == 0)//通过元组参数判断
{
switch(i)//分支判断
{
case 0:
txtBlock.AppendText(m_elems[j].ElementId.ToString());//设置文本块文字内容
break;
case 1:
txtBlock.AppendText(m_elems[j].Description);//设置文本块文字内容
break;
case 2:
txtBlock.AppendText(m_elems[j].ElementType.ToString());//设置文本块文字内容
break;
case 3:
txtBlock.AppendText(m_elems[j].IsInvisible.ToString());//设置文本块文字内容
break;
case 4:
txtBlock.AppendText(m_elems[j].IsValid.ToString());//设置文本块文字内容
break;
case 5:
txtBlock.AppendText(m_elems[j].LevelId.ToString());//设置文本块文字内容
break;
}
}
else if(DataFilterMenu.m_tableInfo.Item2 == 1)//通过元组参数判断
{
switch (i)//分支判断
{
case 0:
txtBlock.AppendText(m_elems[j].ElementId.ToString());//设置文本块文字内容
break;
case 1:
txtBlock.AppendText(m_elems[j].Description);//设置文本块文字内容
break;
}
}
else if (DataFilterMenu.m_tableInfo.Item2 == 2)//通过元组参数判断
{
switch (i)//分支判断
{
case 0:
txtBlock.AppendText(m_elems[j].ElementType.ToString());//设置文本块文字内容
break;
case 1:
txtBlock.AppendText(m_elems[j].IsInvisible.ToString());//设置文本块文字内容
break;
}
}
else if (DataFilterMenu.m_tableInfo.Item2 == 3)//通过元组参数判断
{
switch (i)//分支判断
{
case 0:
txtBlock.AppendText(m_elems[j].IsValid.ToString());//设置文本块文字内容
break;
case 1:
txtBlock.AppendText(m_elems[j].LevelId.ToString());//设置文本块文字内容
break;
}
}
TextElement text = (TextElement)TextElement.CreateElement(null, txtBlock);//定义文本元素
TransformInfo transform = new TransformInfo(DTransform3d.FromTranslation(insertPo));//声明变换信息
text.ApplyTransform(transform);//对元素应用变换信息
subElems.Add(text);//将元素添加到列表中
}
}
#endregion
#region MergeIntoCell
m_textTableElem = new CellHeaderElement(dgnModel, "CustomDataTable", DPoint3d.Zero, DMatrix3d.Identity,subElems);//声明单元元素
#endregion
}
}
private void DynamicDrawElems(Element element,DPoint3d locPo)
{
DTransform3d dTransform = DTransform3d.FromTranslation(locPo);//声明变换矩阵
TransformInfo trans = new TransformInfo(dTransform);//声明变换信息
element.ApplyTransform(trans);//对元素应用变换信息
RedrawElems redrawElems = new RedrawElems();//使用元素用于动态绘制
redrawElems.SetDynamicsViewsFromActiveViewSet(Session.GetActiveViewport());//设置视角
redrawElems.DrawMode = DgnDrawMode.TempDraw;//设置绘制模式
redrawElems.DrawPurpose = DrawPurpose.Dynamics;//设置绘制目标
redrawElems.DoRedraw(element);//使用元素用于动态绘制
dTransform.TryInvert(out DTransform3d dTransformInvert);//获得指定矩阵的逆矩阵
trans = new TransformInfo(dTransformInvert);//声明变换信息
element.ApplyTransform(trans);//对元素应用变换信息
}
private void PlaceDataTable(Element element, DPoint3d locPo)
{
TransformInfo trans = new TransformInfo(DTransform3d.FromTranslation(locPo));//声明变换信息
element.ApplyTransform(trans);//对元素应用变换信息
element.AddToModel();//将元素添加到模型中
}
}
}
using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.Elements;
using Bentley.GeometryNET;
using Bentley.MstnPlatformNET.WinForms;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace ExampleofCase.UI
{
//在MicroStation二次开发的环境下使用WinForm时,需要将继承的Form修改为Bentley.MstnPlatformNET.WinForms.Adapter
public partial class DataFilterMenu : Adapter// Form
{
public static Tuple<bool,int> m_tableInfo;//声明元组
private DataTable m_dt;//声明数据列表
public static List<Element> m_elems;//声明元素列表
public DataFilterMenu()
{
InitializeComponent();
}
private void DataFilterMenu_Load(object sender, EventArgs e)//加载界面时触发
{
m_radioButton_usedefault.Checked = true;//设置单选按钮默认值
m_button_importmodel.Enabled = false;//锁定按钮
m_elems = new List<Element>(DataAnalysisTool.DataAnalysisCommand.m_elems);//定义元素列表
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)//下拉框选择索引值修改后触发
{
RenewTableData();
}
private void button1_Click(object sender, EventArgs e)//按钮点击时触发
{
if (m_checkBox_exportExcel.Checked)//判断多选框是否处于选中状态
{
ExportDataGridToExcel();
}
m_tableInfo = new Tuple<bool, int>(m_radioButton_usedefault.Checked, m_comboBox_modelSelection.SelectedIndex);//定义元组
this.Close();//关闭界面
DataAnalysisTool.ElementPlacementCommand.InstallNewInstance();//启动交互式工具
}
private void RenewTableData()
{
m_dt = new DataTable();//定义数据表
DataSet ds = new DataSet();//声明数据设置
m_dt.TableName = " 元素信息 ";//设置图表名称
ds.Tables.Add(m_dt);//在数据设置的图表中添加数据表
if (m_comboBox_modelSelection.SelectedIndex==0|| m_comboBox_modelSelection.SelectedIndex == 1)//判断下拉框索引值
{
m_dt.Columns.Add(" ID ", typeof(string));//对数据表的列添加项
m_dt.Columns.Add(" Desc ", typeof(string));
}
if(m_comboBox_modelSelection.SelectedIndex == 0 || m_comboBox_modelSelection.SelectedIndex == 2)
{
m_dt.Columns.Add(" Type ", typeof(string));
m_dt.Columns.Add(" IsInvisible ", typeof(bool));
}
if(m_comboBox_modelSelection.SelectedIndex == 0 || m_comboBox_modelSelection.SelectedIndex == 3)
{
m_dt.Columns.Add(" IsValid ", typeof(bool));
m_dt.Columns.Add(" LevelId ", typeof(string));
}
m_button_importmodel.Enabled = true;//激活按钮
foreach (Element elem in m_elems)//遍历列表中的元素
{
DataRow drow = m_dt.NewRow();//新建数据行
if (m_comboBox_modelSelection.SelectedIndex == 0 || m_comboBox_modelSelection.SelectedIndex == 1)//判断下拉框索引值
{
drow[" ID "] = elem.ElementId.ToString();//对数据行的列设置项
drow[" Desc "] = elem.Description;
}
if (m_comboBox_modelSelection.SelectedIndex == 0 || m_comboBox_modelSelection.SelectedIndex == 2)
{
drow[" Type "] = elem.TypeName;
drow[" IsInvisible "] = elem.IsInvisible;
}
if (m_comboBox_modelSelection.SelectedIndex == 0 || m_comboBox_modelSelection.SelectedIndex == 3)
{
drow[" IsValid "] = elem.IsValid;
drow[" LevelId "] = elem.LevelId.ToString();
}
m_dt.Rows.Add(drow);//对数据表中添加数据行
}
m_dataGridView_elemProps.DataSource = m_dt;//设置数据源为定义的数据表
}
private void ExportDataGridToExcel()
{
SaveFileDialog exe = new SaveFileDialog();//声明文件保存对话框
exe.Filter = "Execl files (*.xls)|*.xls";//确定筛选文件格式
exe.FilterIndex = 0;//设置过滤器索引
exe.RestoreDirectory = true;//设置保存目录
exe.Title = "Export Excel File";//设置标题
exe.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);//设置初始化文件存放位置
exe.FileName = string.Format("{0}_{1}", DateTime.Now.ToString("yyyy-MM-dd HH时mm分ss秒"), "元素信息表");//设置文件名称
DialogResult dr = exe.ShowDialog();//获得对话框结果
if (dr != DialogResult.OK)//判断是否成功获取
{
return;//返回
}
#region 将DataTable中的数据转化为Excel格式的数据
Stream ms = exe.OpenFile();
StreamWriter sw = new StreamWriter(ms, Encoding.Default);
string str = "";
try
{
for (int i = 0; i < m_dt.Columns.Count; i++)
{
if (i > 0)
{
str += "\t";
}
str += m_dt.Columns[i];
}
sw.WriteLine(str);
for (int j = 0; j < m_dt.Rows.Count; j++)
{
string temp = "";
for (int k = 0; k < m_dt.Columns.Count; k++)
{
if (k > 0)
{
temp += "\t";
}
string cell = m_dt.Rows[j][k].ToString();
cell = cell.Replace(" ", "").Replace("\r", "").Replace("\n", "").Replace("\r\n", "");
temp += cell;
}
sw.WriteLine(temp);
}
sw.Close();
ms.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
finally
{
sw.Close();
ms.Close();
}
#endregion
}
}
}
namespace ExampleofCase.UI
{
partial class DataFilterMenu
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle();
this.m_dataGridView_elemProps = new System.Windows.Forms.DataGridView();
this.m_comboBox_modelSelection = new System.Windows.Forms.ComboBox();
this.m_label_filter = new System.Windows.Forms.Label();
this.m_button_importmodel = new System.Windows.Forms.Button();
this.m_radioButton_usedefault = new System.Windows.Forms.RadioButton();
this.m_radioButton_usecustom = new System.Windows.Forms.RadioButton();
this.m_checkBox_exportExcel = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.m_dataGridView_elemProps)).BeginInit();
this.SuspendLayout();
//
// m_dataGridView_elemProps
//
this.m_dataGridView_elemProps.AllowUserToAddRows = false;
this.m_dataGridView_elemProps.AllowUserToDeleteRows = false;
dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.m_dataGridView_elemProps.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4;
this.m_dataGridView_elemProps.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle5.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.m_dataGridView_elemProps.DefaultCellStyle = dataGridViewCellStyle5;
this.m_dataGridView_elemProps.Location = new System.Drawing.Point(12, 29);
this.m_dataGridView_elemProps.Name = "m_dataGridView_elemProps";
this.m_dataGridView_elemProps.ReadOnly = true;
dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle6.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.m_dataGridView_elemProps.RowHeadersDefaultCellStyle = dataGridViewCellStyle6;
this.m_dataGridView_elemProps.Size = new System.Drawing.Size(479, 212);
this.m_dataGridView_elemProps.TabIndex = 0;
//
// m_comboBox_modelSelection
//
this.m_comboBox_modelSelection.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.m_comboBox_modelSelection.FormattingEnabled = true;
this.m_comboBox_modelSelection.Items.AddRange(new object[] {
"所有属性",
"模式一",
"模式二",
"模式三"});
this.m_comboBox_modelSelection.Location = new System.Drawing.Point(73, 4);
this.m_comboBox_modelSelection.Name = "m_comboBox_modelSelection";
this.m_comboBox_modelSelection.Size = new System.Drawing.Size(121, 21);
this.m_comboBox_modelSelection.TabIndex = 1;
this.m_comboBox_modelSelection.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// m_label_filter
//
this.m_label_filter.AutoSize = true;
this.m_label_filter.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.m_label_filter.Location = new System.Drawing.Point(11, 5);
this.m_label_filter.Name = "m_label_filter";
this.m_label_filter.Size = new System.Drawing.Size(56, 17);
this.m_label_filter.TabIndex = 2;
this.m_label_filter.Text = "过滤条件";
//
// m_button_importmodel
//
this.m_button_importmodel.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.m_button_importmodel.Location = new System.Drawing.Point(217, 257);
this.m_button_importmodel.Name = "m_button_importmodel";
this.m_button_importmodel.Size = new System.Drawing.Size(75, 23);
this.m_button_importmodel.TabIndex = 3;
this.m_button_importmodel.Text = "导入模型";
this.m_button_importmodel.UseVisualStyleBackColor = true;
this.m_button_importmodel.Click += new System.EventHandler(this.button1_Click);
//
// m_radioButton_usedefault
//
this.m_radioButton_usedefault.AutoSize = true;
this.m_radioButton_usedefault.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.m_radioButton_usedefault.Location = new System.Drawing.Point(14, 247);
this.m_radioButton_usedefault.Name = "m_radioButton_usedefault";
this.m_radioButton_usedefault.Size = new System.Drawing.Size(74, 21);
this.m_radioButton_usedefault.TabIndex = 4;
this.m_radioButton_usedefault.TabStop = true;
this.m_radioButton_usedefault.Text = "内置图表";
this.m_radioButton_usedefault.UseVisualStyleBackColor = true;
//
// m_radioButton_usecustom
//
this.m_radioButton_usecustom.AutoSize = true;
this.m_radioButton_usecustom.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.m_radioButton_usecustom.Location = new System.Drawing.Point(14, 270);
this.m_radioButton_usecustom.Name = "m_radioButton_usecustom";
this.m_radioButton_usecustom.Size = new System.Drawing.Size(86, 21);
this.m_radioButton_usecustom.TabIndex = 5;
this.m_radioButton_usecustom.TabStop = true;
this.m_radioButton_usecustom.Text = "自定义图表";
this.m_radioButton_usecustom.UseVisualStyleBackColor = true;
//
// m_checkBox_exportExcel
//
this.m_checkBox_exportExcel.AutoSize = true;
this.m_checkBox_exportExcel.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.m_checkBox_exportExcel.Location = new System.Drawing.Point(411, 6);
this.m_checkBox_exportExcel.Name = "m_checkBox_exportExcel";
this.m_checkBox_exportExcel.Size = new System.Drawing.Size(80, 21);
this.m_checkBox_exportExcel.TabIndex = 6;
this.m_checkBox_exportExcel.Text = "导出Excel";
this.m_checkBox_exportExcel.UseVisualStyleBackColor = true;
//
// DataFilterMenu
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(505, 292);
this.Controls.Add(this.m_checkBox_exportExcel);
this.Controls.Add(this.m_radioButton_usecustom);
this.Controls.Add(this.m_radioButton_usedefault);
this.Controls.Add(this.m_button_importmodel);
this.Controls.Add(this.m_label_filter);
this.Controls.Add(this.m_comboBox_modelSelection);
this.Controls.Add(this.m_dataGridView_elemProps);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.Name = "DataFilterMenu";
this.ShowIcon = false;
this.Text = "DataFilterMenu";
this.TopMost = true;
this.Load += new System.EventHandler(this.DataFilterMenu_Load);
((System.ComponentModel.ISupportInitialize)(this.m_dataGridView_elemProps)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridView m_dataGridView_elemProps;
private System.Windows.Forms.ComboBox m_comboBox_modelSelection;
private System.Windows.Forms.Label m_label_filter;
private System.Windows.Forms.Button m_button_importmodel;
private System.Windows.Forms.RadioButton m_radioButton_usedefault;
private System.Windows.Forms.RadioButton m_radioButton_usecustom;
private System.Windows.Forms.CheckBox m_checkBox_exportExcel;
}
}
图纸自动生成工具
在目前的设计模式中,作为表达工程信息的载体,如何生成一系列符合标准的图纸是衡量价值的重要标准,同时,生成图纸的效率与准确性也体现了生产力与质量。对于一些较为标准的构件,我们可以根据其特点抽象出其构建规则,以适用于该大类的所有构件,使用二次开发的方式自动根据模型信息生成图纸,与传统的图纸绘制相比,从模型到图纸的过程使用编程的方式自动生成,从而大幅度的提高制图效率。
需求说明:
使用工具对生成的构件进行图纸的输出。
要求:
通过绘制确定构件的最终形态,并在生成的图纸上对构件执行二维标注。
分析:
该工具大致可分为两个阶段:绘制构件阶段与生成图纸阶段,前者需要使用交互式工具,绘制出用于出图的构件,后者会依次创建NamedBoundary,SavedView与DrawingModel,并将SavedView参考到模型中,最后执行图纸中构件的标注。
图4 图纸自动生成工具流程图
using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.Elements;
using Bentley.GeometryNET;
using Bentley.MstnPlatformNET;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ExampleofCase.CreateBeamDrawing
{
class CreateBeamDrawingCommand : DgnElementSetTool
{
#region enum
private enum ViewType//设置枚举类型
{
MainView,//枚举项
LeftView,
VerticalView
}
#endregion
private List<DPoint3d> m_pos;//声明坐标列表
private DgnFile m_dgnFile;//声明文件
private DgnModel m_dgnModel;//声明模型空间
private double m_uorPerMilliMeter;//声明单位分辨率与毫米的比值
public CreateBeamDrawingCommand(int toolId, int prompt) : base(toolId, prompt)//继承基类的构造函数
{
}
public static void InstallNewInstance()//该命令的入口函数
{
CreateBeamDrawingCommand primitiveTool = new CreateBeamDrawingCommand(0, 0);//创建实例
primitiveTool.InstallTool();//加载工具
}
/*
* 如果我们对通过参数传递进来的元素进行修改,并且返回SUCCESS的话,在_DoOperationForModify
* 中会用修改后的元素替换掉原来的元素,当然前提是_IsModifyOriginal返回true。否则的话会直接
* 把修改后的元素重新添加到Dgn文件中。
*/
public override StatusInt OnElementModify(Element element)
{
return StatusInt.Error;
}
protected override void OnRestartTool()//重启工具时触发
{
}
protected override void OnPostInstall()//工具激活后执行
{
m_dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的文件
m_dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的模型
m_uorPerMilliMeter = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter / 1000;//分辨率单位转换为毫米
m_pos = new List<DPoint3d>();//初始化列表
}
protected override bool OnDataButton(DgnButtonEvent ev)//点击确认键(默认为左键)后触发
{
if (m_pos.Count() == 0)//判断列表中的坐标点个数
{
m_pos.Add(ev.Point);//将坐标值添加到列表中
BeginDynamics();//启动动态绘制
return true;//返回
}
else
{
EndDynamics();//关闭动态绘制
m_pos.Add(ev.Point);//将坐标值添加到列表中
Element solid= CreateBeamElem();//创建构建梁的元素
CreateBeamDrawing(solid);
m_pos.Clear();//清空列表
return true;//返回
}
}
protected override bool OnResetButton(DgnButtonEvent ev)//点击重置键(默认为右键)触发
{
if (m_pos.Count() == 0)//判断列表中坐标点个数是否为零
{
ExitTool();//退出工具
}
else
{
EndDynamics();//关闭动态绘制
m_pos.Clear();//清空列表
}
return true;
}
protected override void OnDynamicFrame(DgnButtonEvent ev)//动态绘制时触发
{
ShapeElement m_beamProfile = CreateBeamProfile(m_pos[0]);//创建形元素用于确定梁截面
Element element = CreateSolidElement(m_pos[0], ev.Point, m_beamProfile);//创建梁实体元素
if (null == element)//若未成功生成梁实体元素
return;//返回
DynamicDrawElems(element);//动态绘制元素
}
private ShapeElement CreateBeamProfile(DPoint3d startPo)//创建用于表达梁截面的形元素
{
DPoint3d[] pos =
{
new DPoint3d(startPo.X-0.5*400*m_uorPerMilliMeter,startPo.Y,startPo.Z),
new DPoint3d(startPo.X-0.5*400*m_uorPerMilliMeter,startPo.Y,startPo.Z-1*600*m_uorPerMilliMeter),
new DPoint3d(startPo.X+0.5*400*m_uorPerMilliMeter,startPo.Y,startPo.Z-1*600*m_uorPerMilliMeter),
new DPoint3d(startPo.X+0.5*400*m_uorPerMilliMeter,startPo.Y,startPo.Z)
};//确定梁截面端点坐标集
ShapeElement beamProfile = new ShapeElement(m_dgnModel, null, pos);//创建表达梁截面的形元素
return beamProfile;//返回梁截面的形元素
}
private void DynamicDrawElems(Element element)
{
RedrawElems redrawElems = new RedrawElems();//使用元素用于动态绘制
redrawElems.SetDynamicsViewsFromActiveViewSet(Session.GetActiveViewport());//设置视角
redrawElems.DrawMode = DgnDrawMode.TempDraw;//设置绘制模式
redrawElems.DrawPurpose = DrawPurpose.Dynamics;//设置绘制目标
redrawElems.DoRedraw(element);//使用元素用于动态绘制
}
private SurfaceOrSolidElement CreateSolidElement(DPoint3d startPo, DPoint3d endPo, ShapeElement beamProfile)
{
DVector3d vector = new DVector3d(startPo, endPo);//声明梁方向向量
if (vector == DVector3d.Zero)//判断是否成功获取
{
return null;//返回空
}
TransformInfo trans = new TransformInfo(DTransform3d.FromRotationAroundLine(startPo, DVector3d.UnitZ, vector.Rotate90CCWXY().AngleXY));//声明变换信息
beamProfile.ApplyTransform(trans);//对形元素施加变换
SurfaceOrSolidElement solid = SolidElement.CreateProjectionElement(m_dgnModel, null, beamProfile, startPo, vector, DTransform3d.Identity, true);//创建拉伸实体
return solid;//返回拉伸实体
}
private Element CreateBeamElem()
{
ShapeElement beamProfile = CreateBeamProfile(m_pos[0]);//创建表达梁截面的形元素
SurfaceOrSolidElement solid = CreateSolidElement(m_pos[0], m_pos[1], beamProfile);//创建拉伸实体元素
solid.AddToModel();//将拉伸实体元素写入模型
return solid;//返回拉伸实体元素
}
private void CreateDimensionElem(List<DPoint3d> pos,DgnModel dgnModel, ViewType viewType)
{
List<DPoint3d> reverserPos = new List<DPoint3d>();//声明用于储存坐标的列表
switch (viewType)//分支判断
{
case ViewType.VerticalView://若viewType为ViewType.VerticalView
reverserPos.Add(pos[0]);//对列表添加坐标
reverserPos.Add(pos[1]);
break;
case ViewType.MainView:
reverserPos.Add(new DPoint3d(pos[0].Y, -pos[0].Z));
reverserPos.Add(new DPoint3d(pos[1].Y, -pos[1].Z));
break;
case ViewType.LeftView:
reverserPos.Add(new DPoint3d(pos[0].X, pos[0].Z));
reverserPos.Add(new DPoint3d(pos[1].X, pos[1].Z));
break;
}
//获取当前dgn文件中名字为"DimStyle"的标注样式,尺寸标注元素的外貌由上百个属性控制,而标注样式是一组预先设置好的属性
//获取了预先订制好的标注样式之后,还可以调用DimensionStyle下的各种SetXXX成员函数修改设置的属性
DimensionStyle dimStyle = new DimensionStyle("DimStyle", m_dgnFile);//定义标注样式
dimStyle.SetBooleanProp(true, DimStyleProp.Placement_UseStyleAnnotationScale_BOOLINT);//设置标注样式
dimStyle.SetDoubleProp(1, DimStyleProp.Placement_AnnotationScale_DOUBLE);
dimStyle.SetBooleanProp(true, DimStyleProp.Text_OverrideHeight_BOOLINT);
dimStyle.SetDistanceProp(0.2 * 10000, DimStyleProp.Text_Height_DISTANCE, dgnModel);
dimStyle.SetBooleanProp(true, DimStyleProp.Text_OverrideWidth_BOOLINT);
dimStyle.SetDistanceProp(0.2 * 10000, DimStyleProp.Text_Width_DISTANCE, dgnModel);
dimStyle.SetBooleanProp(true, DimStyleProp.General_UseMinLeader_BOOLINT);
dimStyle.SetDoubleProp(0.01, DimStyleProp.Terminator_MinLeader_DOUBLE);
dimStyle.SetBooleanProp(true, DimStyleProp.Value_AngleMeasure_BOOLINT);
dimStyle.SetAccuracyProp((byte)AnglePrecision.Use1Place, DimStyleProp.Value_AnglePrecision_INTEGER);
int alignInt = (int)DimStyleProp_General_Alignment.True;
StatusInt status = dimStyle.SetIntegerProp(alignInt, DimStyleProp.General_Alignment_INTEGER);
dimStyle.GetIntegerProp(out int valueOut, DimStyleProp.General_Alignment_INTEGER);
DgnTextStyle textStyle = new DgnTextStyle("TestStyle", m_dgnFile);//设置文字样式
LevelId lvlId = Settings.GetLevelIdFromName("Default");//设置图层
CreateDimensionCallbacks callbacks1 = new CreateDimensionCallbacks(dimStyle, textStyle, new Symbology(), lvlId, null);//尺寸标注元素的构造函数会调用DimensionCreateData的各个成员函数去获取定义尺寸标注元素需要的各种参数
CreateDimensionElem(dgnModel,reverserPos, callbacks1,dimStyle,DMatrix3d.Identity);//调用封装的方法创建标注元素
Angle angle = new Angle();//声明角度
angle.Degrees = 90;//设置角度为90度
DMatrix3d matrix = DMatrix3d.XYRotation(angle);//声明旋转90度的变换矩阵
CreateDimensionCallbacks callbacks2 = new CreateDimensionCallbacks(dimStyle, textStyle, new Symbology(), lvlId, null);//尺寸标注元素的构造函数会调用DimensionCreateData的各个成员函数去获取定义尺寸标注元素需要的各种参数
CreateDimensionElem(dgnModel, reverserPos, callbacks2, dimStyle, matrix);//调用封装的方法创建标注元素
}
private void CreateDimensionElem(DgnModel dgnModel, List<DPoint3d> reverserPos, CreateDimensionCallbacks callbacks, DimensionStyle dimStyle, DMatrix3d matrix)
{
DimensionElement dimEle = new DimensionElement(dgnModel, callbacks, DimensionType.SizeStroke);//定义标注元素
if (dimEle.IsValid)//判断标注元素是否有效
{
for (int i = 0; i < reverserPos.Count(); i++)//遍历列表
{
dimEle.InsertPoint(reverserPos[i] - reverserPos[0] - 0.5 * (reverserPos[1] - reverserPos[0]), null, dimStyle, -1);//对标注元素设置插入点
}
dimEle.SetHeight(2 * 10000);//设置尺寸标注元素的高度
dimEle.SetRotationMatrix(DMatrix3d.Identity);//设置变换信息
}
dimEle.SetRotationMatrix(matrix);//对标注元素应用变换矩阵
dimEle.AddToModel();//将标注元素添加到模型
}
private void CreateBeamDrawing(Element solid)
{
for (int i=0;i<3;i++)//遍历
{
string sheetModelName = "drawingModel";//设置字符串
string namedViewName = "testNamedView";
string groupName = "testGroupName";
string boundaryName = "testBoundName";
sheetModelName = sheetModelName + i;//设置sheet模型名称
namedViewName = namedViewName + i;//设置NamedView名称
groupName += i;//设置NamedGroup名称
boundaryName += i;//设置NamedBoundary名称
ViewType viewType = ViewType.VerticalView;//设置枚举默认值
StandardView stView = StandardView.Top;//设置视图视角
switch (i)//分支判断变量
{
case 1://若i等于1
viewType = ViewType.MainView;//设置枚举值
stView = StandardView.Left;//设置视角值
break;//跳出分支
case 2:
viewType = ViewType.LeftView;
stView = StandardView.Front;
break;
}
NamedBoundary boundary = CreateNamedBoundary(solid, groupName, boundaryName);//使用封装的方法创建NamedBoundary
ViewInformation viewInfo = ZoomElementView(solid, out ShapeElement shape, viewType);//使用封装的方法获得视图信息
NamedView view = CreateNamedView(shape, viewInfo, namedViewName);//使用封装的方法创建NamedView
DgnModel drawingModel = CreateDrawingModel(sheetModelName, view, stView);//使用封装的方法创建DrawingModel
CreateDimensionElem(m_pos, drawingModel, viewType);//使用封装的方法创建标注元素
}
}
private DgnModel CreateDrawingModel(string name, NamedView namedView, StandardView viewMode)
{
DgnModel drawingModel = m_dgnFile.CreateNewModel(out DgnModelStatus error, name, DgnModelType.Drawing, false, null);//在指定文件中创建新模型
DgnAttachment refToCreate = drawingModel.CreateDgnAttachment(m_dgnFile.GetDocument().GetMoniker(), name);//创建模型参照
refToCreate.ApplyNamedView(namedView.Name, 1, 1, new ApplyViewClipOptions(), true, viewMode);//对模型参照添加NamedView
refToCreate.WriteToModel(true);//将模型参照写入模型
refToCreate.NestDepth = 99;//设置深度
refToCreate.SetLocateLock(true);//锁定定位
refToCreate.SetSnapLock(true);//锁定捕捉
return drawingModel;//返回模型
}
private NamedView CreateNamedView(ShapeElement shape, ViewInformation viewInfo,string namedViewName)
{
NamedView view = new NamedView(m_dgnFile, namedViewName);//声明NamedView
view.SetClipElement(shape);//设置剪切元素
view.SetViewInfo(viewInfo);//设置视图信息
view.WriteToFile();//将视图写入文件
return view;//返回视图
}
private ViewInformation ZoomElementView(Element elem, out ShapeElement shape, ViewType viewType)
{
DisplayableElement displayele = elem as DisplayableElement;//转换为显示元素
displayele.CalcElementRange(out DRange3d rangeElem);//计算元素范围框
DPoint3d[] pos=null;//声明坐标数组
switch (viewType)//分支判断
{
case ViewType.VerticalView://若viewType为ViewType.VerticalView
{
pos = new DPoint3d[]//定义坐标数组
{
new DPoint3d(rangeElem.Low.X, rangeElem.Low.Y, 0.5 * (rangeElem.Low.Z + rangeElem.High.Z)),
new DPoint3d(rangeElem.High.X, rangeElem.Low.Y, 0.5 * (rangeElem.Low.Z + rangeElem.High.Z)),
new DPoint3d(rangeElem.High.X, rangeElem.High.Y, 0.5 * (rangeElem.Low.Z + rangeElem.High.Z)),
new DPoint3d(rangeElem.Low.X, rangeElem.High.Y, 0.5 * (rangeElem.Low.Z + rangeElem.High.Z)),
};
break;//跳出分支判断
}
case ViewType.MainView:
{
pos = new DPoint3d[]
{
new DPoint3d(rangeElem.Low.X, 0.5*(rangeElem.Low.Y+ rangeElem.High.Y), rangeElem.Low.Z),
new DPoint3d(rangeElem.High.X,0.5*(rangeElem.Low.Y+ rangeElem.High.Y), rangeElem.Low.Z),
new DPoint3d(rangeElem.High.X,0.5*(rangeElem.Low.Y+ rangeElem.High.Y), rangeElem.High.Z),
new DPoint3d(rangeElem.Low.X, 0.5*(rangeElem.Low.Y+ rangeElem.High.Y), rangeElem.High.Z),
};
break;
}
case ViewType.LeftView:
{
pos = new DPoint3d[]
{
new DPoint3d(0.5*(rangeElem.Low.X+ rangeElem.High.X), rangeElem.Low.Y, rangeElem.Low.Z),
new DPoint3d(0.5*(rangeElem.Low.X+ rangeElem.High.X),rangeElem.High.Y, rangeElem.Low.Z),
new DPoint3d(0.5*(rangeElem.Low.X+ rangeElem.High.X),rangeElem.High.Y, rangeElem.High.Z),
new DPoint3d(0.5*(rangeElem.Low.X+ rangeElem.High.X), rangeElem.Low.Y, rangeElem.High.Z),
};
break;
}
}
shape = new ShapeElement(m_dgnModel,null, pos);//使用坐标数组定义形元素
double rL = rangeElem.High.X - rangeElem.Low.X ,
rW = rangeElem.High.Y - rangeElem.Low.Y,
rH = rangeElem.High.Z - rangeElem.Low.Z;//计算视图需要所需的范围(x,y,z)
ViewGroupCollection viewcoll = m_dgnFile.GetViewGroups();//获得当前视图组集合
ViewGroup viewgroup = viewcoll.GetActive();//获得当前激活的视图组
viewgroup.FindFirstOpenView(out int viewnumber);//获得第一个打开的视图
ViewInformation viewinfo = viewgroup.GetViewInformation(viewnumber);//获得指定视图编号的视图信息
//设置视图参数
DPoint3d delta = DPoint3d.FromXYZ(rL, rW, rH);//设置视图范围参数
DMatrix3d rotmax = DMatrix3d.Identity;//设置变换参数
//设置视图范围
viewinfo.SetGeometry(rangeElem.Low, delta, rotmax);//对视图信息设置范围框
//viewgroup.SetViewInformation(viewinfo, viewnumber);
//viewgroup.SaveChanges();
//viewgroup.SynchViewDisplay(viewnumber, false, true, false);
////更新视图
//Session.Instance.Keyin("update view extended");
return viewinfo;
}
private NamedBoundary CreateNamedBoundary(Element elem,string boundaryGroupName,string boundaryName)
{
NamedBoundaryGroup boundaryGroup = NamedBoundaryGroup.CreateNamedBoundaryGroup(Session.Instance.GetActiveDgnModel(), boundaryGroupName, "");//创建NamedBoundaryGroup
NamedBoundary boundary = new NamedBoundary();//声明NamedGroup
boundary.ModelRef = m_dgnModel;//设置NamedGroup参照模型
boundary.Name = boundaryName;//设置NamedGroup名称
boundary.DrawingScale = 1;//设置NamedGroup绘制比例
boundary.GraphicalElement = elem;//设置NamedGroup图像元素
boundary.Save();//保存NamedGroup设置
boundaryGroup.InsertBoundary(boundary);//在NamedBoundaryGroup中导入NamedGroup
boundaryGroup.WriteToFile();//将NamedBoundaryGroup信息写入
return boundary;//返回NamedBoundary
}
}
class CreateDimensionCallbacks : DimensionCreateData
{
private DimensionStyle m_dimStyle;
private DgnTextStyle m_textStyle;
private Symbology m_symbology;
private LevelId m_levelId;
private DirectionFormatter m_directionFormatter;
public CreateDimensionCallbacks(DimensionStyle dimStyle, DgnTextStyle textStyle, Symbology symb, LevelId levelId, DirectionFormatter formatter)
{
m_dimStyle = dimStyle;
m_textStyle = textStyle;
m_symbology = symb;
m_levelId = levelId;
m_directionFormatter = formatter;
}
public override DimensionStyle GetDimensionStyle()
{
return m_dimStyle;
}
public override DgnTextStyle GetTextStyle()
{
return m_textStyle;
}
public override Symbology GetSymbology()
{
return m_symbology;
}
public override LevelId GetLevelId()
{
return m_levelId;
}
public override int GetViewNumber()
{
return 0;
}
//此函数返回的旋转矩阵与GetViewRotation返回的旋转矩阵共同定义了尺寸标注元素的方向
public override DMatrix3d GetDimensionRotation()
{
return DMatrix3d.Identity;
}
public override DMatrix3d GetViewRotation()
{
return DMatrix3d.Identity;
}
//用于从数字方向值构造字符串。
public override DirectionFormatter GetDirectionFormatter()
{
return m_directionFormatter;
}
}
}
工程属性与几何构件联动案例
BIM模型作为工程信息的载体,其中的几何元素必将与实际的工程属性相关联。对于参数化模型来说,假如构件上的参数过多,那么在安置后若多个参数化构件同时存在时,就会存在卡顿的现象。<br /> 本案例中针对的是在放置构件并调整工程属性后,所设定的模型参数会实时进行刷新并在构件模型上得以体现,同时在放置后在**没有对工程属性有修改需求**的场景下适用。这样做的好处是在生成构件模型时构件本身并没有被施加参数,在多个构件同时存在的模型中相较于参数化模型,大大提高模型的承载能力与响应速度。<br /> 该案例主要是用到Addin中的事件,它可以监控用户的行为,在用户执行执行行为时就会触发事件,跳转到对应的业务函数中,因此掌握方法的使用对于MicroStation二次开发来说也非常重要。本案例仅是浅尝辄止的为大家介绍了关于工程属性变化的事件,在后续的系列课程中会对其进行详细的介绍。<br />![Slide8.JPG](https://cdn.nlark.com/yuque/0/2022/jpeg/21640708/1647502828187-5f0a6603-4b07-4cfd-91ac-839c5da3ae18.jpeg#clientId=u83c9c1d1-6320-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=576&id=ufa6ccacf&margin=%5Bobject%20Object%5D&name=Slide8.JPG&originHeight=720&originWidth=1280&originalType=binary&ratio=1&rotation=0&showTitle=false&size=62486&status=done&style=none&taskId=u3157445a-8ff9-44e3-9fbd-64bd2915772&title=&width=1024)<br />**图6 工程属性与元素几何联动流程图**
using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.DgnEC;
using Bentley.DgnPlatformNET.Elements;
using Bentley.ECObjects.Instance;
using Bentley.GeometryNET;
using Bentley.MstnPlatformNET;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace ExampleofCase.ElemPropAutoChangedTool
{
class ElemPropAutoChangedCommand
{
private static DgnFile m_dgnFile;//声明文件
private static DgnModel m_dgnModel;//声明模型空间
private const string ITEMTYPELIB = "testLib";//设置ItemTypeLibrary的名称
private const string ITEMTYPE = "testItemType";//设置ItemType的名称
private const string ITEMPROP = "Length";//设置ItemType属性名称
internal static void LanchEvent()
{
m_dgnFile = Session.Instance.GetActiveDgnFile();//定义文件
m_dgnModel = Session.Instance.GetActiveDgnModel();//定义模型空间
if(!CreateECInfo())
{
return;//返回
}
Element element= CreateComplexSolid(10);
AttachItemTypeToElem(element);
csAddins.MyAddin.Addin.XAttributeChangedEvent += Addin_XAttributeChangedEvent;//添加全局事件,当XAttribute变化时触发
}
private static void AttachItemTypeToElem(Element elem)
{
ItemTypeLibrary itemTypeLibrary = ItemTypeLibrary.FindByName(ITEMTYPELIB, m_dgnFile);//根据声明名称获取对应的ItemTypeLibrary
if (null == itemTypeLibrary)//判断文件中是否存在同名ItemTypeLibrary
{
MessageBox.Show("Can't find ItemType Library");//若文件中不存在同名ItemTypeLibrary,则对话框提示未找到ItemTypeLibrary的提示框
return;//返回
}
ItemType itemType = itemTypeLibrary.GetItemTypeByName(ITEMTYPE);//根据声明名称获取对应的ItemType
CustomItemHost host = new CustomItemHost(elem, true);//声明元素的CustomItemHost
IDgnECInstance item = host.ApplyCustomItem(itemType, true);//对CustomItemHost添加ItemType得到EC实例
item.SetValue(ITEMPROP, 10);//设置属性值
EditParameterDefinitions defs = EditParameterDefinitions.GetForModel(m_dgnModel);//获得模型中的参数定义
DgnECInstanceEnabler enabler = DgnECManager.Manager.ObtainInstanceEnabler(m_dgnFile, itemType.ECClass);//获得文件中使用指定EC类的EC实例
if (null != enabler && enabler.SupportsCreateInstanceOnElement)//判断是否是否支持对元素挂接EC实例
defs.SetDomainParameters(enabler.SharedWipInstance);//对参数定义设置域参数
item.ScheduleChanges(elem);//对圆锥(台)元素更新ItemType信息
elem.AddToModel();//将圆锥(台)写入模型
}
private static bool CreateECInfo()
{
ItemTypeLibrary itemTypeLibrary = ItemTypeLibrary.FindByName(ITEMTYPELIB, m_dgnFile);//根据声明名称获取对应的ItemTypeLibrary
if (null == itemTypeLibrary)//判断文件中是否存在同名ItemTypeLibrary
{
itemTypeLibrary = ItemTypeLibrary.Create(ITEMTYPELIB, m_dgnFile);//若不存在则进行创建
}
itemTypeLibrary.AddItemType(ITEMTYPE);//在ItemTypeLibrary中创建名为testItemTypeName的ItemType
ItemType itemType = itemTypeLibrary.GetItemTypeByName(ITEMTYPE);//获取创建的ItemType
CustomProperty intProperty = itemType.AddProperty(ITEMPROP);//对该ItemType添加名为IntProperty的属性
intProperty.Type = CustomProperty.TypeKind.Integer;//设置IntProperty的属性类型
intProperty.DefaultValue =10;//为StrProperty设置默认值,若不进行设置则默认为空
bool result = itemTypeLibrary.Write();//将ItemTypeLibrary中的信息进行写入更新
if (!result)//判断写入是否成功
{
MessageBox.Show("Input ItemType failure");//若成功输出输入ItemType成功的提示框
return false;//返回结果
}
return true;//返回结果
}
private static Element CreateComplexSolid(int length)
{
DPoint3d p1 = new DPoint3d(10000, 10000);//定义截面轮廓线端点
DPoint3d p2 = new DPoint3d(10000, -10000);
DPoint3d p3 = new DPoint3d(-10000, -10000);
DPoint3d p4 = new DPoint3d(-10000, 10000);
IList<DPoint3d> pos = new List<DPoint3d>() { p1, p2, p3, p4 };//定义轮廓线端点数组
CurveVector curve = CurveVector.CreateLinear(pos, CurveVector.BoundaryType.Outer, true);//定义轮廓线
DVector3d vector = new DVector3d(0, 0, length * 10000);//定义拉伸向量(包含拉伸长度及方向信息)
DgnExtrusionDetail detail = new DgnExtrusionDetail(curve, vector, true);
/*
* 定义拉伸信息
* baseCurve:截面轮廓曲线
* extrusionVector:拉伸信息
* capped:若启用端盖则为真
*/
SolidPrimitive solid = SolidPrimitive.CreateDgnExtrusion(detail);//使用拉伸信息定义实体
BentleyStatus result = Create.BodyFromSolidPrimitive(out SolidKernelEntity entityOut, solid, m_dgnModel);//使用拉伸实体定义SolidKernelEntity
result = Convert1.BodyToElement(out Element elem, entityOut, null, m_dgnModel);//将SolidKernelEntity转换为元素
return elem;//返回元素
}
private static void Addin_XAttributeChangedEvent(AddIn sender, AddIn.XAttributeChangedEventArgs eventArgs)
{
//XATTRIBUTEID_ECXAttributes=22271和LINKAGEID_ECXAttributes = 22271
if (eventArgs.Change ==AddIn.ChangeTrackKind.ReplaceXAttribute&&
eventArgs.XAttribute.MajorId==22271&&
eventArgs.XAttribute.MinorId == 0
)//判断是否为EC属性修改触发的
{
Element elem = Element.GetFromElementRef(eventArgs.XAttribute.ElemRefPtr);//根据事件参数获得变换所属元素
CustomItemHost host = new CustomItemHost(elem, true);//声明元素的CustomItemHost
IList<IDgnECInstance>instances= host.CustomItems;//获得CustomItemHost的所有EC实例集
foreach (IDgnECInstance instance in instances)//遍历EC实例集
{
IECPropertyValue propVal= instance.GetPropertyValue(ITEMPROP);//获得指定名称的属性
if(propVal!=null)//判断是否成功获得
{
Element element = CreateComplexSolid(propVal.IntValue);
element.ReplaceInModel(elem);//将元素写入模型
}
}
}
}
}
}
图7 工程属性与元素几何联动