符老师 我想读取未打开dgn中元素的材质 结果得不到 代码如下:
string file = @"C:\Users\Administrator\Desktop\测试图片.dgn"; DgnDocument dgnDoc = DgnDocument.CreateForLocalFile(file); DgnFileOwner m_dgnFileOwner = DgnFile.Create(dgnDoc, DgnFileOpenMode.ReadWrite); DgnFile m_dgnFile = m_dgnFileOwner.DgnFile; StatusInt openForReadStatus; Bentley.DgnPlatformNET.DgnFileStatus status; if (DgnFileStatus.Success != (status = m_dgnFile.LoadDgnFile(out openForReadStatus))) { System.Windows.Forms.MessageBox.Show(status.ToString()); return StatusInt.Error; } foreach (Bentley.DgnPlatformNET.ModelIndex index in m_dgnFile.GetModelIndexCollection()) { ModelId ModelId = m_dgnFile.FindModelIdByName(index.Name); Bentley.DgnPlatformNET.StatusInt errorDetails; DgnModel model = m_dgnFile.LoadRootModelById(out errorDetails, ModelId, true, true, true); List<Bentley.DgnPlatformNET.Elements.Element> elemList = model.GetGraphicElements().ToList(); foreach (Element el in elemList) { if(el.ElementId== 73732) { MaterialSearchStatus searchStatus; Material mat = MaterialManager.FindMaterialAttachment(out searchStatus, el, el.DgnModel, true); if (searchStatus != MaterialSearchStatus.Success) { System.Windows.Forms.MessageBox.Show("失败"); } } } } m_dgnFile.ProcessChanges(DgnSaveReason.FileClose); m_dgnFile.Release();
4403.测试图片.dgn
求伟大的符老师指导。
读写外部DGN文件有一定的复杂性,请参考如下帖子中的C++代码(和C#是类似的)
https://communities.bentley.com/communities/other_communities/chinafirst/f/microstation-projectwise/152695/msce-c-u6-dgn
需要调用两个关键的函数FillDictionaryModel和FillSectionsInModel
string file = @"C:\Users\Administrator\Desktop\测试图片.dgn"; DgnDocument dgnDoc = DgnDocument.CreateForLocalFile(file); DgnFileOwner m_dgnFileOwner = DgnFile.Create(dgnDoc, DgnFileOpenMode.ReadWrite); DgnFile m_dgnFile = m_dgnFileOwner.DgnFile; StatusInt openForReadStatus; Bentley.DgnPlatformNET.DgnFileStatus status; if (DgnFileStatus.Success != (status = m_dgnFile.LoadDgnFile(out openForReadStatus))) { System.Windows.Forms.MessageBox.Show(status.ToString()); return StatusInt.Error; } StatusInt suce = m_dgnFile.FillDictionaryModel(); foreach (Bentley.DgnPlatformNET.ModelIndex index in m_dgnFile.GetModelIndexCollection()) { ModelId ModelId = m_dgnFile.FindModelIdByName(index.Name); Bentley.DgnPlatformNET.StatusInt errorDetails; DgnModel model = m_dgnFile.LoadRootModelById(out errorDetails, ModelId, true, true, true); suce = m_dgnFile.FillSectionsInModel(model, DgnModelSections.Model); List<Bentley.DgnPlatformNET.Elements.Element> elemList = model.GetGraphicElements().ToList(); foreach (Element el in elemList) { if(el.ElementId== 73732) { MaterialSearchStatus searchStatus; Material mat = MaterialManager.FindMaterialAttachment(out searchStatus, el, el.DgnModel, true); if (searchStatus != MaterialSearchStatus.Success) { System.Windows.Forms.MessageBox.Show("失败"); } } } } m_dgnFile.ProcessChanges(DgnSaveReason.FileClose); m_dgnFile.Release();
符老师 我添加了 还是不行 是不是材质还得初始化其他的?
不将文件作为当前文件打开确实会有许多影响。我们可以用排除法来诊断问题:
1.C#这段代码 打开的dgn和为打开的dgn都不能读到。(这代码就不能或得)
2.我看了论坛提到用实现接口 IElementGraphicsProcessor 中函数
virtual void _AnnounceElemMatSymb(ElemMatSymbCR matSymb) override { m_MaterialCP = matSymb.GetMaterial();//获得元素的材质 }
经测试 当前的打开的可以。但测试未打开的dgn得不到(加载dgn也加了符老师提的那几句关键代码),求符老师指条明路,如何得到未打开dgn材质
我写了一个测试代码测试了一下,可以从外部DGN中拿到元素的材质(Attached Material而非Assigned Material)。
public static void Material(string unparsed) { string strDgn = "c:\\111\\tu.dgn"; DgnDocument dgnDoc = DgnDocument.CreateForLocalFile(strDgn); DgnFileOwner dgnFileOwner = DgnFile.Create(dgnDoc, DgnFileOpenMode.ReadOnly); DgnFile dgnFile = dgnFileOwner.DgnFile; StatusInt errorStatus; dgnFile.LoadDgnFile(out errorStatus); dgnFile.FillDictionaryModel(); DgnModel dgnModel = dgnFile.LoadRootModelById(out errorStatus, dgnFile.DefaultModelId); dgnFile.FillSectionsInModel(dgnModel, DgnModelSections.All); Element myElem = dgnModel.FindElementById((ElementId)1295L); if (null == myElem) { MessageCenter.Instance.ShowInfoMessage("Can't find element which id=1295", null, true); return; } MaterialSearchStatus searchStatus; Material mat = MaterialManager.FindMaterialAttachment(out searchStatus, myElem, myElem.DgnModel, true); if (searchStatus != MaterialSearchStatus.Success) { MessageCenter.Instance.ShowInfoMessage("Failed in FindMaterialAttachment", null, true); return; } MessageCenter.Instance.ShowInfoMessage("Successful", null, true); dgnFile.Release(); }
测试dgn如下:
tu.dgn
Answer Verified By: Andy
对于 Attached Material是可以, 并且用C++的 IElementGraphicsProcessor 接口也可以获得。但对于Assigned Material 用C++的 IElementGraphicsProcessor 接口就不能获得了。 推测是不是还需要初始化什么? 或者有其他方法获得?
下面代码可同时取得元素的两种材质名称。注意,我将Element改成了DisplayableElement,因为只有DisplayableElment才能取得颜色。
public static void Material(string unparsed) { string strDgn = "c:\\111\\tu.dgn"; DgnDocument dgnDoc = DgnDocument.CreateForLocalFile(strDgn); DgnFileOwner dgnFileOwner = DgnFile.Create(dgnDoc, DgnFileOpenMode.ReadOnly); DgnFile dgnFile = dgnFileOwner.DgnFile; StatusInt errorStatus; dgnFile.LoadDgnFile(out errorStatus); dgnFile.FillDictionaryModel(); DgnModel dgnModel = dgnFile.LoadRootModelById(out errorStatus, dgnFile.DefaultModelId); dgnFile.FillSectionsInModel(dgnModel, DgnModelSections.All); DisplayableElement myElem = dgnModel.FindElementById((ElementId)1295L) as DisplayableElement; if (null == myElem) { MessageCenter.Instance.ShowInfoMessage("Can't find element which id=1295", null, true); return; } string msg = null; MaterialSearchStatus searchStatus; Material matAttached = MaterialManager.FindMaterialAttachment(out searchStatus, myElem, myElem.DgnModel, true); if (searchStatus == MaterialSearchStatus.Success) { msg += "AttachedMaterialName=" + matAttached.Name; } uint color = myElem.GetElementDisplayParameters(true).LineColor; Material matAssigned = MaterialManager.FindMaterialBySymbology(out searchStatus, myElem.LevelId, color, dgnModel, false, true); if (searchStatus == MaterialSearchStatus.Success) { if (null != msg) msg += ", "; msg += "AssignedMaterialName=" + matAssigned.Name; } if (null == msg) msg = "No Material"; MessageCenter.Instance.ShowInfoMessage(msg, null, true); dgnFile.Release(); }
public static void Material2(string unparsed) { Bentley.DgnPlatformNET.DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); Bentley.DgnPlatformNET.DgnFile dgnFile = Session.Instance.GetActiveDgnFile(); //读取当前 model if (0 == dgnModel.GetElementCount(DgnModelSections.Model)) { MessageCenter.Instance.ShowInfoMessage("未找到可读取元素!", null, true); return; } //判断是否为空 ModelElementsCollection eles = Session.Instance.GetActiveDgnModel().GetGraphicElements(); //读取图形元素个数 foreach (Element ele in eles) { if (null == ele) { MessageCenter.Instance.ShowInfoMessage("Can't find element which id=1746", null, true); return; } string msg = null; MaterialSearchStatus searchStatus; Bentley.DgnPlatformNET.Material matAttached = MaterialManager.FindMaterialAttachment(out searchStatus, ele, ele.DgnModel, true); //ele.DgnModelRef, if (searchStatus == MaterialSearchStatus.Success) { msg += "AttachedMaterialName=" + matAttached.Name; } if (null == msg) msg = "No Material"; MessageCenter.Instance.ShowInfoMessage(msg, null, true); } }
符老师,我想使用您这个方法批量读取element,在打开当前dgn文档中使用,代码改写后,所有的结果都是No material,之前按照DisplayableElement转换myElem得到的结果都是null,能帮我看一下问题所在吗?
符老师,我说错了,很多element都是null,中间混杂着一些可以读取出的元素,这是什么原因啊?