3个Solid Edge二次开发实用经验帖,赶快收藏备用

服务器

  SolidEdge是Siemens PLM Software公司旗下的三维CAD软件,采用Siemens PLM Software公司自己拥有专利的Parasolid作为软件核心,将普及型CAD系统与世界上最具领先地位的实体造型引擎结合在一起,是基于Windows平台、功能强大且易用的三维CAD软件。扩展阅读:SolidEdge:一款被低估的CAD软件,助你开启高效机械设计解决方案(附学习教程)

  SolidEdge二次开发有COM和Addin两种方式,其中COM(组件对象模型)具有不依赖平台和编程语言等优点,是最常用的一种Solid二次开发方式。

  一、处理应用程序正忙的错误

  当通过外部方式进行访问SolidEdge应用程序时,有可能会报以下异常:

  应用程序正在运行时或未响应(RPC_E_CALL_REJECTED 0x80010001)

  拒绝被调用(RPC_E_SERVERCALL_RETRYLATER 0x8001010A)

  发生这些错误是因为二次开发程序和SolidEdge之间的线程争用问题,可以通过实现IOleMessageFilter接口处理这些异常。

  首先创建OleMessageFilter,实现IOleMessageFilter接口,代码如下:

  namespace UGITCApp

  {

  class OleMessageFilter : IOleMessageFilter

  {

  public static void Register()

  {

  IOleMessageFilter newFilter = new OleMessageFilter();

  IOleMessageFilter oldFilter = null;

  if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)

  {

  CoRegisterMessageFilter(newFilter, out oldFilter);

  }

  else

  {

  throw new COMException("Unable to register message filter because the current thread apartment state is not STA.");

  }

  }

  public static void Revoke()

  {

  IOleMessageFilter oldFilter = null;

  CoRegisterMessageFilter(null, out oldFilter);

  }

  int IOleMessageFilter.HandleInComingCall(

  int dwCallType,

  System.IntPtr hTaskCaller,

  int dwTickCount,

  System.IntPtr lpInterfaceInfo)

  {

  return (int)SERVERCALL.SERVERCALL_ISHANDLED;

  }

  int IOleMessageFilter.RetryRejectedCall(

  System.IntPtr hTaskCallee,

  int dwTickCount,

  int dwRejectType)

  {

  if (dwRejectType == (int)SERVERCALL.SERVERCALL_RETRYLATER)

  {

  return 99;

  }

  return -1;

  }

  int IOleMessageFilter.MessagePing(

  System.IntPtr hTaskCallee,

  int dwTickCount,

  int dwPingType)

  {

  return (int)PINGMSG.PINGMSG_WAITDEFPROCESS;

  }

  [DllImport("Ole32.dll")]

  private static extern int CoRegisterMessageFilter(

  IOleMessageFilter newFilter,

  out IOleMessageFilter oldFilter);

  }

  [ComImport(), Guid("00000016-0000-0000-C000-000000000046"),

  InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]

  interface IOleMessageFilter

  {

  [PreserveSig]

  int HandleInComingCall(

  int dwCallType,

  IntPtr hTaskCaller,

  int dwTickCount,

  IntPtr lpInterfaceInfo);

  [PreserveSig]

  int RetryRejectedCall(

  IntPtr hTaskCallee,

  int dwTickCount,

  int dwRejectType);

  [PreserveSig]

  int MessagePing(

  IntPtr hTaskCallee,

  int dwTickCount,

  int dwPingType);

  }

  }

  使用方法如下:

  static void Main(string[] args)

  {

  OleMessageFilter.Register();

  // Make COM calls.

  OleMessageFilter.Revoke();

  }

  二、获取所有的Application实例对象

  二次开发时,我们通常使用GetActiveObject获取当前激活的SolidEdge的COM接口对象。

  如果打开多个SolidEdge窗口时,如何获取所有的接口对象,通过程序筛选需要的接口对象?这个时候就需要获取当前所有的运行对象表。

  首先引用CreateBindCtx函数,创建绑定上下文对象操作的指针,代码如下:

  通过绑定上下文对象获取运行时对象表,并筛选出指定的接口对象,代码如下:

  调用方法如下,即可获取所有的已经运行的SolidEdge应用接口对象:

  三、如何获取材料信息?

  在开发过程中,SolidEdge的材料表也是很重要的一部分功能,SolidEdge自身有材料库界面,但同样可以通过二次开发获取,我们以2022为例介绍如何获取。

  关键代码如下:

  1、获取材料表对象

  MatTable matTable = SolidEdgeFramework.Application.GetMaterialTable();

  无输入参数,返回SolidEdge的材料表对象MatTable。

  2、获取材料表中材料库

  matTable.GetMaterialLibraryList(out object listOfMaterialLibs, out int numOfMaterialList);

  通过上述的matTable,获取到材料表配置中所有的材料库及数量,每个材料列表包含多种材料。

  3、根据材料列表名称获取材料

  matTable.GetMaterialListFromLibrary(libName, out int materialNums, out object listOfMaterials);

  根据matTable对象,输入libName(材料库名称),输出材料库当中包含的所有材料名称和数量。

  4、获取材料属性

  matTable.GetMaterialPropValueFromLibrary(matName,libName, MatTablePropIndex, out object value);

  根据matTable对象,输入matName(材料名称)、libName(材料库名称)、MatTable Prop Index(材料属性索引),即可获取对应材料属性的值。

  实现效果如下:

  图1 读取材料表

  SolidEdge当中获取材料的关键代码如上所述,效果图中可以看到,在名为Materials的材料库中,名为铝 1350的材料,它的密度属性值为2.712。熟练应用以上4组代码,即可实现对所有材料信息的获取。

  以上三则实用经验你学会了吗?更多关于SE二次开发的问题可以扫码添加小造微信好友(添加时备注:SE),进群交流

标签: 服务器