0564.测试.zip在ORD旗舰版中出现了插入多个单元软件直接崩退的问题,也不会报错,在原来的ORD 10.08版本中就没有出现过这种情况,这是我的测试代码和文件,请各位老师帮忙看看是什么问题导致的, 谢谢
不知道您用中国版本地工具中的放置单元工具测试过没有,单元放置这块本身底层就是MS的接口,看了您的代码,崩溃具体出现再哪一块》?是 BIM.CellElement ele = myApp.CreateCellElement2(cellName, point, scal, true, ma);这句吗?
老师,崩溃的地方我们没找到,单步执行就不会崩溃,直接执行就软件崩退,报错程序信息为 “[10004] OpenRoadsUltimateChina.exe”已退出,返回值为 -1073740940 (0xc0000374)。
2000次我这边也会出异常退出,不过我仔细检查了一下代码,您一次keyin命令执行过程中,存在多处对元素修改的地方,但是您在刚生成元素以后就将其添加到文件中,后边每一次修改就调用一次ReWrite去保存,往文件里边保存是一个很耗时的操作,异常也可能出在频繁保存这里,我改了一下,对Cell全部修改完以后再写入dgn文件,就不会出错了,如下代码所示:
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; using BMI = Bentley.MstnPlatformNET.InteropServices; namespace AddinsOri { public enum myWinFont { 黑体 = 0, 仿宋 = 1, 宋体 = 2, } class Test { //获取当前文件的设计单位 static double UorPerMas = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster; public static void addCell() { Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.AttachCellLibrary(@"D:\公路_路线标注_标准 - 副本.cel"); for (int i = 0; i < 2000; i++) { try { addCellAndReplaceText("十字网格", new DPoint3d(0, 0), DMatrix3d.Identity, "宋体", 3.0 / 1000, 2.4 / 1000, "N", "E", "Default"); } catch(Exception ex) { } } } private static BIM.Element addCellAndReplaceText(string CellName, DPoint3d Pt, DMatrix3d DMA, string fontName, double fontHeight, double fontWidth, string txtA, string txtB, string levelName) { BIM.Application myApp = BMI.Utilities.ComApp; ////工作空间文件路径 //string WorkSpacePath = ConfigurationManager.GetVariable("_USTN_WORKSPACEROOT"); //string cellFile = WorkSpacePath + "\\Standards\\Cell\\路线平面_标注.cel"; //app.AttachCellLibrary(cellFile);//连接数据库 BIM.CellElement cell = insertCell(CellName, new DPoint3d(0, 0), new DPoint3d(1, 1, 1), DMatrix3d.Identity); if (cell == null) return cell; ReplaceTextInCell(ref cell, fontName, fontHeight, fontWidth, txtA, txtB); cell.Level = getLevelByLevelName(levelName); //CE元素转BIM元素 BIM.Transform3d tran = new BIM.Transform3d(); BIM.Point3d BIMPt = myApp.Point3dFromXY(Pt.X, Pt.Y); BIM.Matrix3d ma = new BIM.Matrix3d(); BIM.Point3d DVX = myApp.Point3dFromXYZ(1, 0, 0); BIM.Point3d DVY = myApp.Point3dFromXYZ(0, 1, 0); BIM.Point3d DVZ = myApp.Point3dFromXYZ(0, 0, 1); ma = myApp.Matrix3dFromPoint3dRows(DVX, DVY, DVZ); tran = myApp.Transform3dFromMatrix3dPoint3d(ref ma, ref BIMPt); cell.Transform(ref tran); myApp.ActiveModelReference.AddElement(cell); //打开元素的注释比例锁 long eleID = cell.ID; ElementId ids = new ElementId(ref eleID); Element elel = Session.Instance.GetActiveDgnModel().FindElementById(ids); AnnotationHandler annoHandler = AnnotationHandler.GetAsAnnotationHandler(elel); if (null != annoHandler) { annoHandler.AddAnnotationScale(Session.Instance.GetActiveDgnModel()); annoHandler.ReplaceInModel(elel); } return cell; } /// <summary> /// 在单元元素中替换文字或者线 /// </summary> /// <param name="myCell"></param> /// <param name="txtA">A要替换的文字, 不替换请写""</param> /// <param name="txtB">B要替换的文字, 不替换请写""</param> /// <param name="len">线的长度,不改填0</param> /// <param name="字体">用户选的字体</param> /// <param name="fontHeight">字高</param> /// <param name="fontHeight">字宽</param> /// <param name="JZ居中对齐">文字放置点是否居中</param> private static void ReplaceTextInCell(ref BIM.CellElement myCell, string fontName, double fontHeight, double fontWidth, string txtA = "", string txtB = "") { var subEls = myCell.GetSubElements(); while (subEls.MoveNext()) { var subEl = subEls.Current; if (subEl.Type == BIM.MsdElementType.Text) { BIM.TextElement curTxtEle = (BIM.TextElement)subEl; string temp = null; if (curTxtEle.Text == "A" && txtA != "")//上 { curTxtEle.Text = txtA; } else if (curTxtEle.Text == "B" && txtB != "")//下 { curTxtEle.Text = txtB; } } } } /// <summary> /// 创建标注样式并写字 /// </summary> /// <param name="fixedPt">放置点</param> /// <param name="width">字宽,毫米级</param> /// <param name="height">字高,毫米级</param> /// <param name="text">文字内容</param> /// <param name="dgnModel">当前模型</param> /// <param name="DQFS">文字对齐方式</param> /// <param name="matrix3d">放置矩阵</param> /// <param name="colorIndex">文字颜色</param> /// <returns></returns> private static TextHandlerBase WriteText(string LevelName, DPoint3d fixedPt, double width, double height, myWinFont 字体样式, String text, DgnModel dgnModel, TextElementJustification DQFS, DMatrix3d matrix3d, int colorIndex = 0) { DgnFile dgnFile = Session.Instance.GetActiveDgnFile(); // DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); double UorPerMas = dgnModel.GetModelInfo().UorPerMeter; TextBlockProperties txtBlockProp = new TextBlockProperties(dgnModel); // txtBlockProp.DocumentWidth = 1.5 * UorPerMas; ParagraphProperties paraProp = new ParagraphProperties(dgnModel); paraProp.Justification = DQFS; DgnTextStyle txtStyle = DgnTextStyle.GetSettings(dgnFile); //txtStyle =setTextStyle("ZDM_BZ", "黑体", width, height); txtStyle = activeTextStyle(width, height, 字体样式); //DgnTextStyle textstyle = DgnTextStyle.GetSettings(dgnFile); 获取当前激活文字样式 RunProperties runProp = new RunProperties(txtStyle, dgnModel); TextBlock txtBlock = new TextBlock(txtBlockProp, paraProp, runProp, dgnModel); txtBlock.SetUserOrigin(DPoint3d.Zero); //文本 txtBlock.AppendText(text); TextHandlerBase txtHandlerBase = TextHandlerBase.CreateElement(null, txtBlock); //放文字的坐标 //DPoint3d fix = DPoint3d.FromXY(fixedPt.X - Wh / 15, fixedPt.Y); DTransform3d trans = DTransform3d.FromMatrixAndTranslation(matrix3d, fixedPt); TransformInfo transInfo = new TransformInfo(trans); txtHandlerBase.ApplyTransform(transInfo); //RgbColorDef rgbColorDef = dgnFile.GetColorMap().GetColor(5); //int color = rgbColorDef.ToInt(); ElementPropertiesSetter elePropSet = new ElementPropertiesSetter(); elePropSet.SetColor((uint)colorIndex); elePropSet.Apply(txtHandlerBase); CreateLevel(LevelName, 0, 0, 0, txtHandlerBase); return txtHandlerBase; } private static DgnTextStyle activeTextStyle(double W, double H, Enum myWinFont) { DgnFile dgnFile = Session.Instance.GetActiveDgnFile(); TextStyleCollection tc = dgnFile.GetTextStyles(); DgnTextStyle myTextStyle = null; string FontName = Convert.ToString(myWinFont); foreach (DgnTextStyle ttt in tc) { if (ttt.Name == FontName + "_H" + H.ToString() + "_W" + W.ToString()) { myTextStyle = ttt; break; } } if (myTextStyle == null) { myTextStyle = setTextStyle(FontName + "_H" + H.ToString() + "_W" + W.ToString(), FontName, W, H); } return myTextStyle; } /// <summary> /// 新建图层, 并设置为激活层, 赋予给元素 /// </summary> /// <param name="levelname">层名</param> /// <param name="color">颜色</param> private static void CreateLevel(string levelname, int 颜色, int 线型, int 线宽, Element ele) { //创建新图层层 CreateLevel(levelname, 颜色, 线型, 线宽); FileLevelCache lvlCachaActive = Session.Instance.GetActiveDgnFile().GetLevelCache(); ElementPropertiesSetter elePropSet = new ElementPropertiesSetter(); LevelHandle levelhadle = lvlCachaActive.GetLevelByName(levelname); elePropSet.SetLevel(levelhadle.LevelId); uint bylevel = 4294967295;//16进制(FFFFFFFF)转10进制 elePropSet.SetColor(bylevel); elePropSet.SetWeight(bylevel); LineStyleParameters lspar = null; int bylevels = 2147483647;//16进制(7FFFFFFF)转10进制 elePropSet.SetLinestyle(Convert.ToInt32(bylevels), lspar); elePropSet.Apply(ele); } /// <summary> /// 新建图层, 并设置为激活层 /// </summary> /// <param name="levelname">层名</param> /// <param name="color">颜色</param> private static void CreateLevel(string levelname, int 颜色, int 线型, int 线宽) { bool boo = false; //已经存在该层名 BIM.Application app = BMI.Utilities.ComApp; //创建新图层层 FileLevelCache lvlCachaActive = Session.Instance.GetActiveDgnFile().GetLevelCache(); List<string> strs = new List<string>(); foreach (var level in lvlCachaActive.GetHandles()) { if (level.Name == levelname) { boo = true; BIM.Level pLevel = GetLevelByName(levelname); if (pLevel != null) { app.ActiveSettings.Level = pLevel; //设置为当前激活层 //app.ActiveDesignFile.Levels.Rewrite(); //app.ActiveDesignFile.Save(); } break; } strs.Add(level.Name); } if (boo == false) { EditLevelHandle newLevel = lvlCachaActive.CreateLevel(levelname); LevelDefinitionColor clo = new LevelDefinitionColor((uint)颜色, Session.Instance.GetActiveDgnFile()); newLevel.SetByLevelColor(clo); LineStyleParameters lspar = null; LevelDefinitionLineStyle lineStyle = new LevelDefinitionLineStyle(线型, lspar, Session.Instance.GetActiveDgnFile()); newLevel.SetByLevelLineStyle(lineStyle); newLevel.ByLevelWeight = (uint)线宽; lvlCachaActive.Write(); ////暂停0.5秒,单位毫秒 //System.Threading.Thread.Sleep(300); //app.ActiveDesignFile.RewriteLevels(); BIM.Level pLevel = GetLevelByName(levelname); if (pLevel != null) { app.ActiveSettings.Level = pLevel; //设置为当前激活层 //app.ActiveDesignFile.Levels.Rewrite(); //app.ActiveDesignFile.Save(); //app.SaveSettings(); } } } private static BIM.Level GetLevelByName(string levelName) { BIM.Application app = BMI.Utilities.ComApp; foreach (BIM.Level pLevel in app.ActiveDesignFile.Levels) { if (pLevel.Name.Equals(levelName)) return pLevel; } return null; } private static DgnTextStyle setTextStyle(string DgnFontName, string winFontName, double W, double H, bool Have背景 = false) { //设置字体样式变量 DgnFile dgnFile = Session.Instance.GetActiveDgnFile(); uint foundNum; DgnTextStyle myTextStyle = new DgnTextStyle(DgnFontName, dgnFile); //获取dgnlib中定义过的字体 DgnFont dgnFont = null; DgnLibIterator dgnlibIter = new DgnLibIterator(DgnLibSelector.ElementStyles); foreach (DgnFile dgnlib in dgnlibIter) { if (dgnlib.GetFileName().Contains("Text Favorites_Text Styles_Dimension Styles Metric")) { dgnFont = dgnlib.GetDgnFontMap().FindFontByName(out foundNum, winFontName, DgnFontFilterFlags.All); break; } } myTextStyle.SetFontProperty(TextStyleProperty.Font, dgnFont); //myTextStyle.SetProperty(TextStyleProperty.Color, 5); myTextStyle.SetProperty(TextStyleProperty.Width, W * UorPerMas);//毫米为单位 myTextStyle.SetProperty(TextStyleProperty.Height, H * UorPerMas);//以毫米为单位 if (Have背景 == true) { myTextStyle.SetProperty(TextStyleProperty.Backgroundstyleflag, true);//打开背景颜色 myTextStyle.SetProperty(TextStyleProperty.Backgroundfillcolor, (uint)255); myTextStyle.SetProperty(TextStyleProperty.Backgroundcolor, (uint)255); } //myTextStyle.SetProperty(TextStyleProperty.Justification, (int)TextElementJustification.LeftMiddle); TextStyleCollection tc = dgnFile.GetTextStyles(); bool isIN = false; foreach (DgnTextStyle ttt in tc) { if (ttt.Name == DgnFontName) { isIN = true; break; } } if (isIN == true) { myTextStyle.Replace(DgnFontName, dgnFile); } else { myTextStyle.Add(dgnFile); } return myTextStyle; } private static BIM.Level getLevelByLevelName(string levelName) { bool boo = false; //已经存在该层名 //创建新图层层 FileLevelCache lvlCachaActive = Session.Instance.GetActiveDgnFile().GetLevelCache(); foreach (var level in lvlCachaActive.GetHandles()) { if (level.Name == levelName) { boo = true; } } BIM.Application MsApp = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp; List<string> names = new List<string>(); BIM.Level leve = null; if (boo == true) { foreach (BIM.Level lev in MsApp.ActiveModelReference.Levels) { if (lev.Name == levelName) { leve = lev; } } } return leve; } /// <summary> /// 放置单元 /// </summary> /// <param name="cellLibrary">单元库路径</param> /// <param name="cellName">单元名称</param> /// <param name="point">放置点</param> /// <param name="scal">缩放</param> /// <param name="myMatrix"></param> /// <returns></returns> private static BIM.CellElement insertCell(string cellName, DPoint3d location, DPoint3d scale, DMatrix3d DMa) { BIM.Application myApp = BMI.Utilities.ComApp; DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); BIM.Point3d DX = myApp.Point3dFromXYZ(DMa.RowX.X, DMa.RowX.Y, DMa.RowX.Z); BIM.Point3d DY = myApp.Point3dFromXYZ(DMa.RowY.X, DMa.RowY.Y, DMa.RowY.Z); BIM.Point3d DZ = myApp.Point3dFromXYZ(DMa.RowZ.X, DMa.RowZ.Y, DMa.RowZ.Z); BIM.Matrix3d ma = myApp.Matrix3dFromPoint3dRows(ref DX, ref DY, ref DZ); BIM.Point3d point = myApp.Point3dFromXYZ(location.X, location.Y, location.Z); BIM.Point3d scal = myApp.Point3dFromXYZ(scale.X, scale.Y, scale.Z); BIM.CellElement ele = myApp.CreateCellElement2(cellName, point, scal, true, ma); return ele; } } }
老师,用您改过的代码确实不崩溃了, 但是我们还未实现单元中文字和字体样式的替换修改, 老师有什么好的方法吗, 方便的话可以提供下代码示例吗
搜索以前帖子,如下帖子代码是成功的。供您参考:
老师, 这个试过了, 郭老师提供的就是这种方式实现, 但是不符合我们的需求, 我们需要替换单元中的文字和文字样式, 这个只实现了替换文字, 未实现替换文字样式
文字样式也是作为文字一部分存在的。你只要能成功替换文字,就能替换文字中的文字样式的。
因为文字的属性实在太多,你最好自行编写一个程序先打印所有属性,然后对照着看要如何设置它们。有需要Overwrite标记需要设置后覆盖特性才能起作用。
好的老师