第九期视频回放
第九期代码及课件下载地址
第九期直播内容文字版
本次直播内容主要是对实际生产过程中经常出现的需求进行案例的介绍。从内容上分,主要涉及两个部分,分别为:出图阶段的表格,图纸生成案例与事件驱动的参数化建模案例。
图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;//获得文字样式IDif (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 DrawCustomDataTableint 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 InsertDataToDataTablefor (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 MergeIntoCellm_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.Adapterpublic 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();}#endregionprivate 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 enumprivate enum ViewType//设置枚举类型{MainView,//枚举项LeftView,VerticalView}#endregionprivate 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.VerticalViewreverserPos.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等于1viewType = ViewType.MainView;//设置枚举值stView = StandardView.Left;//设置视角值break;//跳出分支case 2:viewType = ViewType.LeftView;stView = StandardView.Front;break;}NamedBoundary boundary = CreateNamedBoundary(solid, groupName, boundaryName);//使用封装的方法创建NamedBoundaryViewInformation viewInfo = ZoomElementView(solid, out ShapeElement shape, viewType);//使用封装的方法获得视图信息NamedView view = CreateNamedView(shape, viewInfo, namedViewName);//使用封装的方法创建NamedViewDgnModel drawingModel = CreateDrawingModel(sheetModelName, view, stView);//使用封装的方法创建DrawingModelCreateDimensionElem(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);//对模型参照添加NamedViewrefToCreate.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);//声明NamedViewview.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, "");//创建NamedBoundaryGroupNamedBoundary boundary = new NamedBoundary();//声明NamedGroupboundary.ModelRef = m_dgnModel;//设置NamedGroup参照模型boundary.Name = boundaryName;//设置NamedGroup名称boundary.DrawingScale = 1;//设置NamedGroup绘制比例boundary.GraphicalElement = elem;//设置NamedGroup图像元素boundary.Save();//保存NamedGroup设置boundaryGroup.InsertBoundary(boundary);//在NamedBoundaryGroup中导入NamedGroupboundaryGroup.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 /><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);//根据声明名称获取对应的ItemTypeLibraryif (null == itemTypeLibrary)//判断文件中是否存在同名ItemTypeLibrary{MessageBox.Show("Can't find ItemType Library");//若文件中不存在同名ItemTypeLibrary,则对话框提示未找到ItemTypeLibrary的提示框return;//返回}ItemType itemType = itemTypeLibrary.GetItemTypeByName(ITEMTYPE);//根据声明名称获取对应的ItemTypeCustomItemHost host = new CustomItemHost(elem, true);//声明元素的CustomItemHostIDgnECInstance 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);//根据声明名称获取对应的ItemTypeLibraryif (null == itemTypeLibrary)//判断文件中是否存在同名ItemTypeLibrary{itemTypeLibrary = ItemTypeLibrary.Create(ITEMTYPELIB, m_dgnFile);//若不存在则进行创建}itemTypeLibrary.AddItemType(ITEMTYPE);//在ItemTypeLibrary中创建名为testItemTypeName的ItemTypeItemType itemType = itemTypeLibrary.GetItemTypeByName(ITEMTYPE);//获取创建的ItemTypeCustomProperty 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);//使用拉伸实体定义SolidKernelEntityresult = 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 = 22271if (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);//声明元素的CustomItemHostIList<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 工程属性与元素几何联动


