[C# MSCE]读取未打开dgn中元素的材质

符老师    我想读取未打开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

求伟大的符老师指导。

Parents
  • 读写外部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();

    符老师  我添加了   还是不行   是不是材质还得初始化其他的?

  • 我写了一个测试代码测试了一下,可以从外部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();
            }



    Answer Verified By: Andy 

  • 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,中间混杂着一些可以读取出的元素,这是什么原因啊?

Reply Children