[OPM CE C#]如何删除或移动OPM元素

最终目的是移动OPM元素。

先将OPM元素用MS方法,获得一个cellheader元素,然后ApplyTransform,ReplaceInModel。此方法(有别的办法移动么?最好是直接移动OPM元素,现在是没办法才转换成MS元素操作)可以移动除operator外的OPM元素。
opmComponent.ApplyTransform(transInfo);
opmComponent.ReplaceInModel(opmComponent);

同样方法试图移动operator元素,执行到opmOperatorComponent.ReplaceInModel (opmOperatorComponent)时候会报错{"Bad StatusInt: 69645"}。

然后我尝试删除原来的operator,在正确的位置上重新放置。请问如何删除?VS搜索过delete和remove关键字,没找到删除元素的方法。试过ReplaceInModel(Null),也不生效。

Parents
  • 最近也在做OPM开发,遇到有类似问题,这里分享我的研究,仅供参考:

    • 通过GetSelectedInstances获取当前选择的component
    • OpenPlant.Modeler.Api.BMECObject bMECObject = new BMECObject(IECInstance instance);
    • 通过BMECObject中的ElementRefBase*拿到元素,这里会有命名空间冲突,可以用别名解决

    BOMA::Bentley.DgnPlatform.ElementRefBase* eleRef = bMECObject.Element;

    Element ele = Element.GetFromElementRef((IntPtr)eleRef);

    这里拿到的元素就是Component对应的元素,可以考虑对它做移动或删除,当然这也是将其转换成MS元素,如果像直接对Component操作,可以研究BMECObject中有一个Component属性,对齐进行操作,这个就和自定义参数化设备、阀门等API是相似的,这是一个思路,我也没有尝试过

  • 请问接下来是如何对MS元素进行移动或删除?我现在已经通过FindElementById将OPM元素作为MS元素获取了(属性里面看到的是cellheadelement), 根据前面的讨论,需要通过keyin才能移动(确切的说,valve可以通过transform移动,但是operator对象同样操作会报错)或者删除。

    谢谢!

  • 理解,跳过OPM机制进行移动也会跳过一些后台操作。

    关于另一个帖子,参考了里面的代码,使用第三种遍历的方法实现了获得MS元素。

    关于 提到的方法,不明觉厉,感觉是最好的方法,希望能够学习到。

    • 通过GetSelectedInstances获取当前选择的component
    • OpenPlant.Modeler.Api.BMECObject bMECObject = new BMECObject(IECInstance instance);
    • 通过BMECObject中的ElementRefBase*拿到元素,这里会有命名空间冲突,可以用别名解决

    方式。

    第一步我是刚刚创建好OPM元素,所以已经有这个component了。

    第二步OpenPlant.Modeler.Api在C#中不存在,请问如何继续。

    谢谢。

     

  • 这个我也在验证,我是希望能够对已有的Component进行修改操作,发现有这么一个API,还在尝试,这个在其他dll文件中,可以在OPM安装目录下搜索

  • 贴一下我之前的一个回复:

    关于获取生成的Element,对于Pipe,我做过一个测试,您可以参考一下:

    如果是Update 9及之后,试试这个:

                   //Create Pipe.

                    PipeComponentData pipe1Data = new PipeComponentData(specification, nominalDiameter);

                    pipe1Data.SetProperty("LENGTH", length.ToString());

                    PipeComponent pipe1 = new PipeComponent(origin, pipe1Data, 0, DrawingView.ViewTop, true);

                    pipe1.Create();

                    ComponentPropertiesGetter pGetter = new ComponentPropertiesGetter(pipe1);

     

                    // Yes, it is the GUID of the newly created PIPE, I have verified it with the result of "ecx items dump"

                    string guid = pGetter.GetPropertyValue("GUID");

                    Debug.WriteLine(guid);

     

                    // Update 9 之前有bug,不能这样用,下边列出我的Workaround

                    IECInstance instance = DgnUtilities.GetInstanceByGuid(guid);

                    IDgnECInstance dgnInstance = instance as IDgnECInstance;

                    Element element = dgnInstance.Element;

                    Debug.WriteLine(element.ElementId);

    对于Update 8及之前(或者上边的代码如果还是不行),需要使用这个Workaround:

                    //Create Pipe.

                    PipeComponentData pipe1Data = new PipeComponentData(specification, nominalDiameter);

                    pipe1Data.SetProperty("LENGTH", length.ToString());

                    PipeComponent pipe1 = new PipeComponent(origin, pipe1Data, 0, DrawingView.ViewTop, true);

                    pipe1.Create();

                    ComponentPropertiesGetter pGetter = new ComponentPropertiesGetter(pipe1);

     

                    // Yes, it is the GUID of the newly created PIPE, I have verified it with the result of "ecx items dump"

                    string guid = pGetter.GetPropertyValue("GUID");

                    Debug.WriteLine(guid);

     

                    ECInstanceList plantInstanceList = DgnUtilities.GetInstancesFromDgn("PLANT_BASE_OBJECT", true);

                    foreach (IECInstance plantInstance in plantInstanceList)

                        {

                        if (plantInstance["GUID"].StringValue == guid)

                            {

                            IDgnECInstance dgnInstance = plantInstance as IDgnECInstance;

                            Element element = dgnInstance.Element;

                            Debug.WriteLine(element.ElementId);

                            Debug.WriteLine("We found it!"); // Indeed, we found it.

                           // You can operate on the element immediately;

                     // or just cache its “Plant Object Instance GUID” somewhere and operate on them later in a batch.

                            }

                        }

    目前没有找到API能从Element加载得到SDK中的各种XyzComponent,SDK中的各个Component类目前更像是为了创建构件而存在的,查询和修改都可以用标准的EC API完成,OPM SDK中的查询例子也是用的EC 的API实现的,而不是Component API:

    C:\Program Files\Bentley\OpenPlant CONNECT Edition\OpenPlantModeler\SDKExamples\QueryPipeWithPortsExample\MyDialog.cs

    虽然例子中是查询,但也可以设置属性的值,可以结合MicroStation中的EC相关例子理解一下。

    OPM是基于MicroStation的,所以它会尽可能地复用MicroStation的现有功能和API,包括但不限于Keyin和EC。

  • 能否告知是哪个dll?根据前面的讨论,dll跟namedspace未必匹配……

    现在的方法只能是武老师的第三种方法,遍历所有,如果元素多的话就会慢,不是太完美。

    谢谢!

  • 您在找这个?

    C:\Program Files\Bentley\OpenPlant CONNECT Edition\OpenPlantModeler\Assemblies\Bentley.OpenPlant.Modeler.Api.dll

Reply Children
No Data