找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2264|回复: 4

[分享] Net调用Lisp

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2015-1-7 17:43:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Reflection;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using AcRx = Autodesk.AutoCAD.Runtime;
using AcEd = Autodesk.AutoCAD.ApplicationServices;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
#endregion
namespace HLIB.Utils
{
  /// <summary>
  /// VisualLISPと通信。
  /// (vl-load-com)を実行してないとだめ。
  /// </summary>
  public class Lisp : IDisposable
  {
    private bool Disposed = false;
    private object m_vlObj;
    private object m_vlFunc;
    private AcadApplication m_app;
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="acadApp">AutoCAD应用程序</param>
    public Lisp ( AcadApplication acadApp )
    {
      m_app = acadApp;
      try {
        m_vlObj = acadApp.GetInterfaceObject( "VL.Application.16" );
        object acDoc = GetProperty( m_vlObj, "ActiveDocument" );
        m_vlFunc = GetProperty( acDoc, "Functions" );
      } catch {
        AcEd.CommandLinePrompts.Message( " VL未能检测到对象." );
      }
    }
    ~Lisp ()
    {
      Dispose();
    }
    /// <summary>
    /// VlApp 释放使用的资源。
    /// </summary>
    public void Dispose ()
    {
      if ( Disposed == false ) {
        m_vlFunc = null;
        m_vlObj = null;
        m_app = null;
        Disposed = true;
      }
    }
    /// <summary>
    /// COM对象中获取一个属性。
    /// </summary>
    /// <param name="obj">对象</param>
    /// <param name="propName">属性名称</param>
    /// <returns></returns>
    private object GetProperty ( object obj, string propName )
    {
      return obj.GetType().InvokeMember( propName,
        BindingFlags.GetProperty, null, obj, null );
    }
    /// <summary>
    /// COM对象的索引器。
    /// </summary>
    /// <param name="obj">对象</param>
    /// <param name="index">索引名</param>
    /// <returns></returns>
    private object GetIndexer ( object obj, string index )
    {
      return obj.GetType().InvokeMember( "Item",
        BindingFlags.GetProperty, null, obj, new object[] { index } );
    }
    /// <summary>
    /// LISP调用该函数,并返回结果。
    /// </summary>
    /// <param name="funcName">LISP函数名</param>
    /// <param name="args">参数</param>
    /// <returns></returns>
    private object InvokeLispFunction ( string funcName, object[] args )
    {
      object sym = GetIndexer( m_vlFunc, funcName );
      return sym.GetType().InvokeMember( "funcall",
        BindingFlags.InvokeMethod, null, sym, args );
    }
    /// <summary>
    /// 使用Lisp表达式。
    /// </summary>
    /// <param name="lispStatement">LISP表达式</param>
    /// <returns></returns>
    public object Eval ( string lispStatement )
    {
      try {
        object sym = InvokeLispFunction( "read", new object[] { lispStatement } );
        return InvokeLispFunction( "eval", new object[] { sym } );
      } catch {
        AcEd.CommandLinePrompts.Message( " 错误的LISP表达式." );
        return null;
      }
    }
    /// <summary>
    /// 获取一个值,从 LISP 变量。
    /// </summary>
    /// <param name="symbolName">变量名</param>
    /// <returns></returns>
    public object GetValue ( string symbolName )
    {
      try {
        return Eval( symbolName );
      } catch {
        return null;
      }
    }
    /// <summary>
    /// 将该值赋给一个 LISP 变量。
    /// </summary>
    /// <param name="symbolName">变量名</param>
    /// <param name="val">値</param>
    public void SetValue ( string symbolName, object val )
    {
      Eval( "(vl-load-com)" );
      Eval( "(defun translate-variant (data) (cond ((= (type data) 'list) (mapcar 'translate-variant data)) ((= (type data) 'variant) (translate-variant (vlax-variant-value data))) ((= (type data) 'safearray) (mapcar 'translate-variant (vlax-safearray->list data))) (t data)))" );
      Eval( "(setq " + symbolName + " (translate-variant " + val + "))" );
      Eval( "(setq translate-variant nil)" );
    }
    /// <summary>
    /// 分配在 lisp 语言变量中零
    /// </summary>
    /// <param name="symbolName">変量名</param>
    public void SetSymbolsToNil ( params string[] symbolName )
    {
      for ( int i = 0; i < symbolName.Length; i++ ) {
        Eval( "(setq " + symbolName[ i ] + " nil)" );
      }
    }
    /// <summary>
    /// 将数组列表转换。
    /// </summary>
    /// <param name="symList">变量名的列表</param>
    /// <returns></returns>
    public ArrayList GetLispList ( string symList )
    {
      ArrayList ret = new ArrayList();
      object list;
      long len;
      try {
        list = Eval( symList );
        len = ( long )InvokeLispFunction( "length", new object[] { list } );
        for ( long i = 0; i < len; i++ ) {
          ret.Add( InvokeLispFunction( "nth", new object[] { i, list } ) );
        }
      } catch {
      }
      return ret;
    }
    /// <summary>
    /// 从 DXF 代码获取信息。
    /// </summary>
    /// <param name="code">DXF 代码</param>
    /// <param name="symEname">值</param>
    /// <returns></returns>
    private object getDxfData ( int code, object symEname )
    {
      object ent = InvokeLispFunction( "entget", new object[] { symEname } );
      object val = InvokeLispFunction( "assoc", new object[] { code, ent } );
      return InvokeLispFunction( "cdr", new object[] { val } );
    }
    /// <summary>
    /// 将 AcadEntity LSIP 选择集的数组转换为。
    /// </summary>
    /// <param name="symSS">设置变量的名称,其中包含所选内容</param>
    /// <param name="ents">AcadEntity 数组容器</param>
    /// <returns></returns>
    public bool PickSetToSelectionSet ( string symSS, ref AcadEntity[] ents )
    {
      bool ret = false;
      try {
        object ss = Eval( symSS );
        long sslength = ( long )InvokeLispFunction( "sslength", new object[] { ss } );
        ents = new AcadEntity[ sslength ];
        for ( long i = 0; i < sslength; i++ ) {
          object en = InvokeLispFunction( "ssname", new object[] { ss, i } );
          ents[ i ] = ( AcadEntity )( m_app.ActiveDocument.HandleToObject( ( string )getDxfData( 5, en ) ) );
        }
        ret = true;
      } catch {
      }
      return ret;
    }
    /// <summary>
    ///将选定的一组 ActiveX 转换为 LSIP 选择组。
    /// </summary>
    /// <param name="symSS">设置变量的名称,其中包含所选内容</param>
    /// <param name="acadSS">AcadSelectionSet 容器</param>
    /// <returns></returns>
    public bool PickSetToSelectionSet ( string symSS, ref AcadSelectionSet acadSS )
    {
      bool ret = false;
      acadSS.Clear();
      AcadEntity[] ents = null;
      if ( PickSetToSelectionSet( symSS, ref ents ) ) {
        acadSS.AddItems( ents );
        ret = true;
      }
      return ret;
    }
    /// <summary>
    /// 将 ObjectIdCollection 转换为 LSIP 选择组。
    /// </summary>
    /// <param name="symSS">设置变量的名称,其中包含所选内容</param>
    /// <param name="objIds">ObjectIdCollectionの入れ物</param>
    /// <returns></returns>
    public bool PickSetToSelectionSet ( string symSS, ref AcDb.ObjectIdCollection objIds )
    {
      bool ret = false;
      objIds.Clear();
      AcadEntity[] ents = null;
      if ( PickSetToSelectionSet( symSS, ref ents ) ) {
        foreach ( AcadEntity en in ents ) {
          AcDb.ObjectId id = new AcDb.ObjectId();
          id.OldId = en.ObjectID;
          objIds.Add( id );
        }
        ret = true;
      }
      return ret;
    }
    /// <summary>
    /// 将转换为一组选定的  ObjectIdCollection。
    /// </summary>
    /// <param name="objIds">ObjectIdCollection</param>
    /// <param name="symSS">変数名</param>
    /// <returns></returns>
    public bool SelectionSetToPickSet ( AcDb.ObjectIdCollection objIds, string symSS )
    {
      bool ret = false;
      try {
        Eval( "(setq " + symSS + " (ssadd))" );
        foreach ( AcDb.ObjectId id in objIds )
          Eval( "(ssadd (handent "" + id.Handle + "")" + symSS + ")" );
        ret = true;
      } catch {
      }
      return ret;
    }
    /// <summary>
    /// 将转换为一组选定的  AcadSelectionSet。
    /// </summary>
    /// <param name="acadDD">AcadSelectionSet</param>
    /// <param name="symSS">要包括一个选项集的变量名称</param>
    /// <returns></returns>
    public bool SelectionSetToPickSet ( AcadSelectionSet acadSS, string symSS )
    {
      bool ret = false;
      try {
        Eval( "(setq " + symSS + " (ssadd))" );
        foreach ( AcadEntity en in acadSS )
          Eval( "(ssadd (handent "" + en.Handle + "")" + symSS + ")" );
        ret = true;
      } catch {
      }
      return ret;
    }
  }
}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 112个

财富等级: 日进斗金

发表于 2015-10-10 14:30:32 | 显示全部楼层
谢谢楼主分享
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2015-10-14 14:54:13 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2016-1-3 21:07:38 来自手机 | 显示全部楼层
vlax的调用方式。。。这个很不稳定
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2016-1-3 21:10:05 来自手机 | 显示全部楼层
高版本应该有Application.Invoke直接调用lisp函数  低版本平台调用arx的函数也比这个好些
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-27 01:38 , Processed in 0.483868 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表