Mstn中有很多种类型的元素,我们可以将其分成图形元素和非图形元素。本章主要讨论如何在Addin中利用Mstn对象模型创建图形元素。下图是CE版本Addins的整体架构。其中我们创建图形元素用到的对象主要在DgnPlatformNET下。
有关Mstn对象模型更详细的信息请参考位于…\ Bentley\MicroStationCONNECTSDK\doc文件夹下的帮助文档。另外,当你在VS中引用了Mstn对象模型后也能通过VS中的对象浏览器查看到整个对象模型,如下图所示。(VS中的对象浏览器是通过选VS菜单View > Object Browser打开的)
既然了解了图形元素的一些知识,就让我们通过一步步的操作在DGN模型中建立一些图形元素。
1.在解决方案浏览器中右击csAddins,选菜单Add > New Item…,在弹出的窗体中选Visual C# Items下的Class,文件名输入CreateElement.cs。点击Add按钮为当前项目添加一个新的CreateElement.cs文件。
2.修改并键入代码。最终的CreateElement.cs文件内容如下。其中绘制了九组元素,分别是LineAndLineString1、LineAndLineString2、LineAndLineString3、ShapeAndComplexShape、TextString、Cell、Dimension、BsplineCurve和Cone。
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 BIM = Bentley.Interop.MicroStationDGN; namespace csAddins { //尺寸标注元素的构造函数会调用DimensionCreateData的各个成员函数去获取创建尺寸标注元素需要的各种参数 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; } } class CreateElement { //函数后台坐标值使用的单位都是Uor单位,我们需要将传递给函数接口的值从主单位乘上此值变为Uor单位 static double UorPerMas = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster; //创建图形元素首先按框架分有两种创建方式,正如我们在第零章中开头部分介绍的那样,本函数简单演示了从v8i继承的COM接口创建图形元素的方式 public static void LineAndLineString1() { //从v8i继承的编程框架创建元素的函数都在Bentley.Interop.MicroStationDGN.Application接口下 BIM.Application app = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp; BIM.Point3d ptStart = app.Point3dZero(); BIM.Point3d ptEnd = ptStart; //使用这套编程框架时,函数接受参数的单位都是主单位,这一点是跟新的编程框架最大的不同之处 ptStart.X = 10; BIM.LineElement lineEle = app.CreateLineElement2(null, ref ptStart, ref ptEnd); lineEle.Color = 0; lineEle.LineWeight = 2; app.ActiveModelReference.AddElement(lineEle); } //新的编程框架下创建元素的方式又可以分为两大种,本函数演示了其中一种直接通过特定类型元素的构造函数去构造,直接将坐标值传递给 //特定类型的构造函数去创建指定类型的元素 public static void LineAndLineString2() { DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); ModelInfo modelInfo = dgnModel.GetModelInfo(); DSegment3d seg = new DSegment3d(0 * UorPerMas, 5 * UorPerMas, 0 * UorPerMas, 10 * UorPerMas, 10 * UorPerMas, 0 * UorPerMas); LineElement lineEle = new LineElement(dgnModel, null, seg); lineEle.AddToModel(); DPoint3d[] ptArr = new DPoint3d[5]; ptArr[0] = new DPoint3d(15 * UorPerMas, 10 * UorPerMas, 0 * UorPerMas); ptArr[1] = new DPoint3d(16 * UorPerMas, 12 * UorPerMas, 0 * UorPerMas); ptArr[2] = new DPoint3d(18 * UorPerMas, 8 * UorPerMas, 0 * UorPerMas); ptArr[3] = new DPoint3d(20 * UorPerMas, 12 * UorPerMas, 0 * UorPerMas); ptArr[4] = new DPoint3d(21 * UorPerMas, 10 * UorPerMas, 0 * UorPerMas); LineStringElement lineStrEle = new LineStringElement(dgnModel, null, ptArr); lineStrEle.AddToModel(); } //本函数演示了新框架下另外一种创建图形元素的方法,即先构造图形元素的几何数据,最后调用统一的DraftingElementSchema.ToElement函数完成几何数据到特定类型元素的创建 public static void LineAndLineString3() { DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); ModelInfo modelInfo = dgnModel.GetModelInfo(); DPoint3d[] ptArr = new DPoint3d[5]; ptArr[0] = new DPoint3d(0 * UorPerMas, 10 * UorPerMas, 0 * UorPerMas); ptArr[1] = new DPoint3d(1 * UorPerMas, 12 * UorPerMas, 0 * UorPerMas); ptArr[2] = new DPoint3d(3 * UorPerMas, 8 * UorPerMas, 0 * UorPerMas); ptArr[3] = new DPoint3d(5 * UorPerMas, 12 * UorPerMas, 0 * UorPerMas); ptArr[4] = new DPoint3d(6 * UorPerMas, 10 * UorPerMas, 0 * UorPerMas); //CurvePrimitive仅仅保存基本曲线的几何数据,不包含Mstn元素的其他任何数据(例如元素的颜色,线型等属性) CurvePrimitive curPri = CurvePrimitive.CreateLineString(ptArr); //DraftingElementSchema.ToElement将几何数据转换成Mstn中对应类型的元素(ArcElement,LineElement等) Element ele = DraftingElementSchema.ToElement(dgnModel, curPri, null); ele.AddToModel(); } public static void ShapeAndComplexShape() { DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); DPoint3d[] ptArr = new DPoint3d[6]; ptArr[0] = new DPoint3d(0 * UorPerMas, -6 * UorPerMas, 0 * UorPerMas); ptArr[1] = new DPoint3d(0 * UorPerMas, -2 * UorPerMas, 0 * UorPerMas); ptArr[2] = new DPoint3d(2 * UorPerMas, -2 * UorPerMas, 0 * UorPerMas); ptArr[3] = new DPoint3d(2 * UorPerMas, -4 * UorPerMas, 0 * UorPerMas); ptArr[4] = new DPoint3d(4 * UorPerMas, -4 * UorPerMas, 0 * UorPerMas); ptArr[5] = new DPoint3d(4 * UorPerMas, -6 * UorPerMas, 0 * UorPerMas); ShapeElement shapeEle = new ShapeElement(dgnModel, null, ptArr); //ElementPropertiesSetter用来设置元素Symbol属性(颜色,线型等属性) ElementPropertiesSetter elePropSet = new ElementPropertiesSetter(); elePropSet.SetColor(0); elePropSet.SetWeight(2); elePropSet.Apply(shapeEle); shapeEle.AddToModel(); for (int i = 0; i < 6; i++) ptArr[i].X += 5 * UorPerMas; CurvePrimitive curvePri = CurvePrimitive.CreateLineString(ptArr); //CurveVector是CurvePrimitive的集合,用来表示任意复杂的线型几何数据 CurveVector curVec = CurveVector.Create(CurveVector.BoundaryType.Outer); curVec.Add(curvePri); ptArr[2].Y = -8; DEllipse3d ellipse = new DEllipse3d(); if (DEllipse3d.TryCircularArcFromCenterStartEnd(ptArr[2], ptArr[5], ptArr[0], out ellipse)) { curvePri = CurvePrimitive.CreateArc(ellipse); curVec.Add(curvePri); Element eleTemp = DraftingElementSchema.ToElement(dgnModel, curVec, null); eleTemp.AddToModel(); elePropSet.SetColor(1); elePropSet.SetWeight(2); elePropSet.Apply(eleTemp); eleTemp.AddToModel(); } } //文本元素需要的各种参数分了Block,Paragraph,Run等层级,每一层设置其包含的属性,有点类似于Word中的管理结构 public static void TextString() { DgnFile dgnFile = Session.Instance.GetActiveDgnFile(); DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); TextBlockProperties txtBlockProp = new TextBlockProperties(dgnModel); txtBlockProp.IsViewIndependent = true; ParagraphProperties paraProp = new ParagraphProperties(dgnModel); DgnTextStyle txtStyle = DgnTextStyle.GetSettings(dgnFile); RunProperties runProp = new RunProperties(txtStyle, dgnModel); TextBlock txtBlock = new TextBlock(txtBlockProp, paraProp, runProp, dgnModel); txtBlock.AppendText("This is a textBlock Element"); TextHandlerBase txtHandlerBase = TextHandlerBase.CreateElement(null, txtBlock); DTransform3d trans = DTransform3d.Identity; trans.Translation = new DVector3d(6 * UorPerMas, 2 * UorPerMas, 3 * UorPerMas); //UOR unit TransformInfo transInfo = new TransformInfo(trans); //对图形元素进行旋转平移的变换可以将元素变换到任意位置,此处只做了平移变换,没有旋转 txtHandlerBase.ApplyTransform(transInfo); txtHandlerBase.AddToModel(); } //单元是由若干个子元素加一个单元头元素构成的复杂元素,子元素也可是一个单元 public static void Cell() { DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); DPoint3d[] ptArr = new DPoint3d[5]; ptArr[0] = new DPoint3d(-15 * UorPerMas, -5 * UorPerMas, 0 * UorPerMas); ptArr[1] = new DPoint3d(-15 * UorPerMas, 5 * UorPerMas, 0 * UorPerMas); ptArr[2] = new DPoint3d(-5 * UorPerMas, 5 * UorPerMas, 0 * UorPerMas); ptArr[3] = new DPoint3d(-5 * UorPerMas, -5 * UorPerMas, 0 * UorPerMas); ptArr[4] = new DPoint3d(-15 * UorPerMas, -5 * UorPerMas, 0 * UorPerMas); ShapeElement shapeEle = new ShapeElement(dgnModel, null, ptArr); DPlacementZX dPlaceZX = DPlacementZX.Identity; dPlaceZX.Origin = new DPoint3d(-10 * UorPerMas, 0, 0); DEllipse3d ellipse = new DEllipse3d(dPlaceZX, 5 * UorPerMas, 5 * UorPerMas, Angle.Zero, Angle.TWOPI); EllipseElement elliEle = new EllipseElement(dgnModel, null, ellipse); List<Element> listEle = new List<Element>(); listEle.Add(shapeEle); listEle.Add(elliEle); DPoint3d ptOri = new DPoint3d(); DMatrix3d rMatrix = DMatrix3d.Identity; DPoint3d ptScale = new DPoint3d(1, 1, 1); CellHeaderElement cellHeaderEle = new CellHeaderElement(dgnModel, "CellElementSample", ptOri, rMatrix, listEle); cellHeaderEle.AddToModel(); } public static void Dimension() { DgnFile dgnFile = Session.Instance.GetActiveDgnFile(); DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); double uorPerMast = dgnModel.GetModelInfo().UorPerMaster; //获取当前dgn文件中名字为"DimStyle"的标注样式,尺寸标注元素的外貌由上百个属性控制,而标注样式是一组预先设置好的属性 //获取了预先订制好的标注样式之后,还可以调用DimensionStyle下的各种SetXXX成员函数修改设置的属性 DimensionStyle dimStyle = new DimensionStyle("DimStyle", 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.5 * uorPerMast, DimStyleProp.Text_Height_DISTANCE, dgnModel); dimStyle.SetBooleanProp(true, DimStyleProp.Text_OverrideWidth_BOOLINT); dimStyle.SetDistanceProp(0.4 * uorPerMast, 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); int valueOut; dimStyle.GetIntegerProp(out valueOut, DimStyleProp.General_Alignment_INTEGER); DgnTextStyle textStyle = new DgnTextStyle("TestStyle", dgnFile); LevelId lvlId = Settings.GetLevelIdFromName("Default"); CreateDimensionCallbacks callbacks = new CreateDimensionCallbacks(dimStyle, textStyle, new Symbology(), lvlId, null); DimensionElement dimEle = new DimensionElement(dgnModel, callbacks, DimensionType.SizeArrow); if (dimEle.IsValid) { DPoint3d pt1 = DPoint3d.Zero, pt2 = DPoint3d.FromXY(uorPerMast * 10, uorPerMast * 0); dimEle.InsertPoint(pt1, null, dimStyle, -1); dimEle.InsertPoint(pt2, null, dimStyle, -1); //设置尺寸标注元素的高度 dimEle.SetHeight(uorPerMast); DMatrix3d rMatrix = DMatrix3d.Identity; dimEle.SetRotationMatrix(rMatrix); dimEle.AddToModel(); } } public static void BsplineCurve() { DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); DPoint3d[] ptArr = new DPoint3d[5]; ptArr[0] = new DPoint3d(0 * UorPerMas, 25 * UorPerMas, 0 * UorPerMas); ptArr[1] = new DPoint3d(5 * UorPerMas, 35 * UorPerMas, 0 * UorPerMas); ptArr[2] = new DPoint3d(10 * UorPerMas, 25 * UorPerMas, 0 * UorPerMas); ptArr[3] = new DPoint3d(15 * UorPerMas, 35 * UorPerMas, 0 * UorPerMas); ptArr[4] = new DPoint3d(20 * UorPerMas, 25 * UorPerMas, 0 * UorPerMas); MSBsplineCurve msBsplineCurve = MSBsplineCurve.CreateFromPoles(ptArr, null, null, 3, false, true); CurvePrimitive curvePri = CurvePrimitive.CreateBsplineCurve(msBsplineCurve); Element ele = DraftingElementSchema.ToElement(dgnModel, curvePri, null); ele.AddToModel(); } public static void Cone() { DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); DPoint3d ptTop = new DPoint3d(2 * UorPerMas, -15 * UorPerMas, 0 * UorPerMas); DPoint3d ptBottom = new DPoint3d(2 * UorPerMas, -15 * UorPerMas, 3 * UorPerMas); DMatrix3d rMatrix = DMatrix3d.Identity; ConeElement coneEle = new ConeElement(dgnModel, null, 2 * UorPerMas, 1 * UorPerMas, ptTop, ptBottom, rMatrix, true); coneEle.AddToModel(); } } }
4.打开MyAddins.cs文件修改如下。
protected override int Run(string[] commandLine) { CreateElement.LineAndLineString1(); CreateElement.LineAndLineString2(); CreateElement.LineAndLineString3(); CreateElement.ShapeAndComplexShape(); CreateElement.TextString(); CreateElement.Cell(); CreateElement.Dimension(); CreateElement.BsplineCurve(); CreateElement.Cone(); return 0; }
5.通过选菜单Build > Build Solution来重新生成目标文件。记住,在执行生成前要记住退出Mstn。
6.启动Mstn,装载csAddins程序,则能看到如下图所示的图形。请注意,你当前的DGN文件模型应该是一个三维模型,否则Cone方法将不能被正确执行。
在以上代码中我们用了三种方法画线元素。LineAndLineString1用的是CE版本之前Addins开放框架。LineAndLineString2用的是CE上Addins开发框架,通过元素类型的构造函数创建元素。LineAndLineString3用的是CE上Addins开发框架的一种全新的创建元素的方法,即先创建几何,最后通过DraftingElementSchema 下的静态成员函数ToElement把几何转换为元素。我们可以看到CE Addins框架为我们提供了丰富的创建元素的方法,具体使用哪一种我们可以根据实际情况选择。