明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 8328|回复: 27

[运行时] 如何编写代码实现从外部输入块,并插入到当前文件中?

  [复制链接]
发表于 2013-3-30 21:01 | 显示全部楼层 |阅读模式
大家好。
采用代码可以绘制简单的图形,但有时有些图形很复杂,采用代码绘制时很繁琐,故我想请问一下,有没有可能将这些复杂图形预先做成块保存在独立的dwg文件中,在自己编写的程序运行时再从这个dwg文件中导入到运行的文档中,这样做是可行的吗?如何操作?请给我给点提示啊。
发表于 2013-3-30 22:08 | 显示全部楼层
建议LZ找一个图库就可以解决你的问题
发表于 2013-3-31 08:04 | 显示全部楼层
    /// <summary>
    /// 使用一个新建的database从另外一个不打开的文件引入块记录
    /// ImportBlock_DB里的ReadDwgFile方法在编译调试环境下会出错,错误为:尝试读取或写入受保护的内存
    /// 但在正常AutoCAD启动装载程序情况下可用
    /// Version : 2008.11.11 Sieben
    /// </summary>
    /// <param name="fileName">另外一个文件的文件名</param>
    /// <param name="blockName">引入的一个块记录名,若为空字符串"",将引入文件里面的全部图块</param>
    /// <returns>成功返回true,否则返回false</returns>
    static public StringCollection ImportBlock_DB(string fileName, string blockName)
    {
      if (!File.Exists(fileName)) return null;
      Database sourceDb = new Database(false, true);
      try
      {
        //下面的ReadDwgFile方法在编译调试环境下会出错,错误为:尝试读取或写入受保护的内存
        //但在正常AutoCAD启动装载程序情况下可用.
        sourceDb.ReadDwgFile(fileName, System.IO.FileShare.Read, false, "");
        Database destDb = aApp.DocumentManager.MdiActiveDocument.Database;
        ObjectIdCollection blockIds = new ObjectIdCollection();
        StringCollection reValue = new StringCollection();
        using (Transaction ctrans = sourceDb.TransactionManager.StartTransaction())
        {
          BlockTable cbt = (BlockTable)ctrans.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);
          if (blockName == "")
          {
            foreach (ObjectId btrId in cbt)
            {
              BlockTableRecord cbtr = (BlockTableRecord)ctrans.GetObject(btrId, OpenMode.ForRead, false);
              if (!cbtr.IsAnonymous && !cbtr.IsLayout)
              {
                blockIds.Add(btrId);
                reValue.Add(cbtr.Name);
              }
              cbtr.Dispose();
            }
          }
          else if (cbt.Has(blockName))
          {
            blockIds.Add(cbt[blockName]);
          }
          cbt.Dispose();
        }
        if (blockIds.Count == 0)
        {
          return null;
        }
        else
        {
          IdMapping mapping = new IdMapping();
          sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, new IdMapping(), DuplicateRecordCloning.Replace, false);
          return reValue;
        }
      }
      catch (System.Exception ex)
      {      
        se.WriteMessage(ex);
        return null;
      }
      finally { sourceDb.Dispose(); }
    }
发表于 2013-3-31 08:06 | 显示全部楼层
   /// <summary>
    /// 将dwg文件作为图块引入
    /// 备注:
    /// 1,不生成块参考
    /// 2,应对文件Insbase不是原点的情况 2011.04.23
    /// Version : 2011.04.23 Sieben
   /// </summary>
    /// <param name="fileName">dwg文件全名</param>
   /// <param name="blockName">生成的块记录名,输入空字符串时将使用文件名作为块记录名(不含扩展名)</param>
   /// <param name="replace">若对应的块记录名已存在,是否替换</param>
   /// <returns>若成功返回块记录的ObjectId,否则返回ObjectId.Null </returns>
    static public ObjectId InsertDwg(string fileName, ref string blockName, bool replace)
    {
      try
      {
        if (!replace)
        {
          ObjectId blockId = sn.GetRecordId(sc.db.BlockTableId, blockName);
          if (blockId != ObjectId.Null)
            return blockId;
        }
        if (fileName == "" || !File.Exists(fileName))
          return ObjectId.Null;
        if (!fileName.ToLower().EndsWith(".dwg"))
          return ObjectId.Null;
      }
      catch (System.Exception ex)
      {
        se.WriteMessage(ex);
        return ObjectId.Null;
      }
      Database newDB = new Database(false, false);
      bool newDBHasDispose = false;
      try
      {
        if (blockName == "")
        {
          FileInfo fileInfo = new FileInfo(fileName);
          blockName = fileInfo.Name.Substring(0, fileInfo.Name.Length - 4);
        }
        newDB.ReadDwgFile(fileName, System.IO.FileShare.Read, true, fileName);
        if (newDB.Insbase.GetAsVector().Length > 0.00001)
        {
          if (newDB.Insbase.X >= newDB.Extmin.X && newDB.Insbase.X <= newDB.Extmax.X
            && newDB.Insbase.Y >= newDB.Extmin.Y && newDB.Insbase.Y <= newDB.Extmax.Y)
          {
            //Insbase位于图形范围,不进行移动,有可能不符合预期
            return sc.db.Insert(blockName, newDB, true);
          }
          else
          {
            if (newDB.Extmin.X > newDB.Extmax.X)
            {
              //图形范围Extmin Extmax未初始化,不进行移动,有可能不符合预期
               return sc.db.Insert(blockName, newDB, true);
            }
            else
            {
              Matrix3d tMat = Matrix3d.Displacement(newDB.Insbase.GetAsVector().Negate());
              newDB.Insbase = Point3d.Origin;
              ObjectId blockId = sc.db.Insert(blockName, newDB, true);
              if (0 >= newDB.Extmin.X && 0 <= newDB.Extmax.X  && 0 >= newDB.Extmin.Y && 0 <= newDB.Extmax.Y)
              {
                //坐标原点位于图形范围,不进行移动,有可能不符合预期
                 return blockId;
              }
              else
              {
                //Insbase不位于图形范围 坐标原点也不位于图形范围,将图形从Insbase移到原点,有可能不符合预期
                using (Transaction ctrans = sc.db.TransactionManager.StartTransaction())
                {
                  BlockTableRecord cbtr = (BlockTableRecord)ctrans.GetObject(blockId, OpenMode.ForWrite);
                  foreach (ObjectId tId in cbtr)
                  {
                    Entity ent = (Entity)ctrans.GetObject(tId, OpenMode.ForWrite);
                    ent.TransformBy(tMat);
                  }
                  ctrans.Commit();
                }
                return blockId;
              }
            }

          }
        }
        else
        {
          //Insbase位于原点,不用做任何处理
          return sc.db.Insert(blockName, newDB, true);
        }
      }
      catch (System.Exception ex)
      {
        se.WriteMessage(ex);
        return ObjectId.Null;
      }
      finally
      {
        if (!newDBHasDispose)
          newDB.Dispose();
      }
    }
发表于 2013-3-31 08:07 | 显示全部楼层
sc.db = HostApplicationServices.WorkingDatabase
 楼主| 发表于 2013-3-31 19:28 | 显示全部楼层
sieben 发表于 2013-3-31 08:07
sc.db = HostApplicationServices.WorkingDatabase

你好,sieben。
请问,在你的第二个解答方案中定义的变量“sc,se,sn”是怎么定义的,请再详细一点,谢谢。
发表于 2013-4-1 12:52 | 显示全部楼层
          ObjectId blockId = sn.GetRecordId(sc.db.BlockTableId, blockName);
          if (blockId != ObjectId.Null)
            return blockId;
---------------------
这里是检查当前Dwg文件有没有同名图块,其他没有什么了,你可以注销这些代码
 楼主| 发表于 2013-4-1 14:58 | 显示全部楼层
sieben 发表于 2013-4-1 12:52
ObjectId blockId = sn.GetRecordId(sc.db.BlockTableId, blockName);
          if (blockId ! ...

你好,sieben。
谢谢帮助,你的第二个方法在我这里调试通了。但我还有点问题。
你的第二个函数InsertDwg()一定要是静态的吗?
第二个函数InsertDwg()的第二个形参为啥一定要传指针?“ref string blockName” ?
这个函数返回的应该是插入的块的Objectid吧?
 楼主| 发表于 2013-4-1 16:01 | 显示全部楼层
本帖最后由 介之推 于 2013-4-1 16:05 编辑

你好,sieben。
你的第二个函数调试通了以后,编译不出问题,我这样调用你的InsertDwg()函数,运行时出错了,显示的是“eSelfReference”,就是自引用了,不知道问题出现在哪里?
这是我的调用函数。
  1. [CommandMethod("IB")]
  2.         public void InsertBlock()
  3.         {
  4.             Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             try
  8.             {
  9.                 using (Transaction trans = db.TransactionManager.StartTransaction())
  10.                 {
  11.                     //ImportBlock_DB("test.dwg", "sample");
  12.                     string blockName = "sample"; InsertDwg("test.dwg", ref blockName);

  13.                     trans.Commit();
  14.                 }
  15.             }
  16.             catch (System.Exception ex)
  17.             {               
  18.                 ed.WriteMessage(ex.StackTrace + "\n" + ex.Message + "\n" + ex.TargetSite);
  19.                 return;
  20.             }
  21.                      
  22.         }


出错的代码在这里

  1. if (newDB.Insbase.GetAsVector().Length > 0.00001)
  2.                 {
  3.                     //中间部分么有改动
  4.                 }
  5.                 else
  6.                 {
  7.                     //Insbase位于原点,不用做任何处理
  8.                     //return sc.db.Insert(blockName, newDB, true);
  9.                     return myDb.Insert(blockName, newDB, true);         //这行出错了,错误信息:eSelfReference
  10.                 }
复制代码


发表于 2013-4-1 18:45 | 显示全部楼层
介之推 发表于 2013-4-1 14:58
你好,sieben。
谢谢帮助,你的第二个方法在我这里调试通了。但我还有点问题。
你的第二个函数InsertDw ...

1,否
2,不解析,无所谓
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-9 06:15 , Processed in 0.269397 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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