[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();

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

Reply
  • 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();

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

Children
  • 不将文件作为当前文件打开确实会有许多影响。我们可以用排除法来诊断问题:

    1. 从外部打开文件能否取得该元素的其他信息?不能,说明你的程序没有写对;能,说明你的程序可以操作外部文件中的元素了。
    2. 将该文件作为当前文件打开,执行你的提取材质的代码是否正确?不正确,请修改提取材质代码。正确,则说明确实是从外部打开的方式下无法提取材质信息。



  • 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();
            }



    Answer Verified By: Andy