xgr 发表于 2012-8-25 12:11:42

如何插入一个已定义于dwg之外的块

如巳定义好一个块文件,现需插入进新建图内,看了好多贴子,都是在本图内新建一个块.与我的要求不一样,求一个通用函数,

xgr 发表于 2012-8-27 11:28:03

就如insert命令,从外部选择一个图块插入,这里真冷清,没办法,c#太菜,求助高手明示一下,谢谢了.

mkhsj928 发表于 2012-8-27 12:02:25

      public static ObjectId m_ImportBlock(string fileName, string blockName, bool bReplace)
      {
            ObjectId destId = mFun.m_GetBlockId(blockName);
            if (destId.IsNull)
            {
                using (Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())//记住一定要先锁定文档
                {
                  using (Database sourceDb = new Database(false, false))
                  {
                        sourceDb.ReadDwgFile(fileName.Trim(), FileShare.Read, true, null);

                        //destId = mCommands.m_db.Insert(blockName, sourceDb, false);//错误?!?!块自参照???!!!

                        destId = m_ImportBlock(sourceDb, blockName, bReplace);

                        sourceDb.CloseInput(true);
                  }
                }
            }

            return destId;
      }
      public static ObjectId m_ImportBlock(Database sourceDb, string blockName, bool bReplace)
      {
            ObjectId destId = ObjectId.Null;
            using (Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
            {
                using (Transaction sourceTr = sourceDb.TransactionManager.StartTransaction())
                {
                  BlockTable sourceBt = sourceTr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead) as BlockTable;

                  if (sourceBt.Has(blockName))
                  {
                        ObjectId sourceId = sourceBt;

                        IdMapping idmap = new IdMapping();
                        sourceDb.WblockCloneObjects(
                            new ObjectIdCollection(new ObjectId[] { sourceId }),
                            HostApplicationServices.WorkingDatabase.BlockTableId,
                            idmap,
                            bReplace == true ? DuplicateRecordCloning.Replace : DuplicateRecordCloning.MangleName,
                            false);

                        destId = idmap.Value;
                  }

                  sourceTr.Commit();
                }
            }

            return destId;
      }

xgr 发表于 2012-8-27 13:28:12

就如insert命令,从外部选择一个图块插入,这里真冷清,没办法,c#太菜,求助高手明示一下,谢谢了.

xgr 发表于 2012-8-27 17:02:29

mkhsj928 发表于 2012-8-27 12:02


发现三个错误
1 当前下文中不存在名称"mFun";
2 “WblockCloneObjects”方法没有任何重载采用五个参数;
3 无法将带[]的索引应于"Autodesk.Autocad.DatabaseServices.Idmapping"

mkhsj928 发表于 2012-8-28 09:49:20

xgr 发表于 2012-8-27 17:02 static/image/common/back.gif
发现三个错误
1 当前下文中不存在名称"mFun";
2 “WblockCloneObjects”方法没有任何重载采用五个参数 ...

1."ObjectId destId = mFun.m_GetBlockId(blockName);
             if (destId.IsNull)"——可以不要,作用是检查当前图形中是否已存在同名块.
2."WblockCloneObjects"出现错误?你的CAD版本是不是低了?
3.怀疑你的CAD版本低了,请用08以上版本

xgr 发表于 2012-8-28 10:40:16

是否可以换个版本
我是CAD2006+VS2010+NET3.5
没办法,有些软件必须用CAD2006

mkhsj928 发表于 2012-8-28 10:46:40

主要是WblockCloneObjects这个函数了,你用06版重新编译,看看06版的这个函数的参数,修改试试看
电脑里面没06版了,所以不好改

single-yu 发表于 2012-9-9 11:46:58

本帖最后由 single-yu 于 2012-9-9 11:47 编辑

我用的就是CAD2006+VS2005,一直都用的很正常,你试试我的这个代码:
我的程序是这样的,在外部建个DWG文件作为模板,每次调用它插入到图形中,并作修改!

                        '开始当前文档的事务处理
                        Using trans As Transaction = curDb.TransactionManager.StartTransaction
                            '新建临时数据库来读取点之记模板
                            Dim tempDb As New Database(False, True)
                            '新建数据库来生成点之记
                            Dim db As New Database(False, True)
                            '使用多边形框来选择范围内的实体
                            Dim resSel As PromptSelectionResult = ed.SelectCrossingPolygon(ptColl)
                            Dim sSet As SelectionSet = resSel.Value
                            Dim Ids As ObjectIdCollection = New ObjectIdCollection(sSet.GetObjectIds)
                            Ids.Add(pLine.ObjectId)
                            db = curDb.Wblock(Ids, curDb.Ucsorg)

                            '读取点之记模板
                            Dim fileName As String = "C:\Program Files\AcadTool\测量工具箱\TP.dwg" '模板文件的位置
                            If System.IO.File.Exists(fileName) Then
                              tempDb.ReadDwgFile(fileName, System.IO.FileShare.Read, True, Nothing)
                              tempDb.CloseInput(True)
                              '插入点之记模板文件到数据库
                              db.Insert(System.IO.Path.GetFileNameWithoutExtension(fileName), tempDb, True)

                              '开始点之记数据库的事务处理
                              Using atrans As Transaction = db.TransactionManager.StartTransaction
                                    Dim bt As BlockTable = atrans.GetObject(db.BlockTableId, OpenMode.ForWrite)

                                    If bt.Has("TP") = False Then
                                        Return
                                    End If

                                    Dim block As BlockTableRecord = atrans.GetObject(bt.Item("TP"), OpenMode.ForWrite)

                                    '字体样式
                                    Dim tst As TextStyleTable = TryCast(atrans.GetObject(db.TextStyleTableId, OpenMode.ForWrite), TextStyleTable)

                                    '添加TP点点名
                                    Dim tpName As New DBText
                                    '在点之记中加入作业员
                                    Dim workmanText As New DBText
                                    '在点之记中加入检查员
                                    Dim checkmanText As New DBText
                                    '在点之记中加入说明
                                    Dim typeText As New MText


                                    tpName.TextString = "TP" & num.ToString
                                    tpName.Position = New Point3d(-30, -69, 0)
                                    tpName.Height = 4
                                    tpName.TextStyle = atrans.GetObject(tst.Item("宋体"), OpenMode.ForWrite).ObjectId

                                    workmanText.TextString = pointMarkPalette.textboxWorkMan.Text
                                    workmanText.Position = New Point3d(-55.65, -100.32, 0)
                                    workmanText.Height = 4
                                    workmanText.TextStyle = atrans.GetObject(tst.Item("宋体"), OpenMode.ForWrite).ObjectId

                                    checkmanText.TextString = pointMarkPalette.textboxCheckMan.Text
                                    checkmanText.Position = New Point3d(-2.86, -100.32, 0)
                                    checkmanText.Height = 4
                                    checkmanText.TextStyle = atrans.GetObject(tst.Item("宋体"), OpenMode.ForWrite).ObjectId

                                    typeText.Contents = "1、实地砸有" & pointMarkPalette.typeCbo.Text & ",并涂有红油漆。"
                                    typeText.Location = New Point3d(-49.235, -137.553, 0)
                                    typeText.TextHeight = 4
                                    typeText.TextStyle = atrans.GetObject(tst.Item("宋体"), OpenMode.ForWrite).ObjectId


                                    block.AppendEntity(tpName)
                                    block.AppendEntity(workmanText)
                                    block.AppendEntity(checkmanText)
                                    block.AppendEntity(typeText)

                                    atrans.AddNewlyCreatedDBObject(tpName, True)
                                    atrans.AddNewlyCreatedDBObject(workmanText, True)
                                    atrans.AddNewlyCreatedDBObject(checkmanText, True)
                                    atrans.AddNewlyCreatedDBObject(typeText, True)

                                    Dim blockref As BlockReference = New BlockReference(pt, bt.Item("TP"))
                                    '点之记根据比例尺缩小或者放大
                                    blockref.ScaleFactors = New Scale3d(ScaleFlector)
                                    blockref.Rotation = 0
                                    Dim btr As BlockTableRecord = atrans.GetObject(bt.Item(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                                    btr.AppendEntity(blockref)
                                    atrans.AddNewlyCreatedDBObject(blockref, True)
                                    atrans.Commit()
                              End Using

                            End If
                            '把临时存取模板的数据库销毁
                            tempDb.Dispose()
                            '保存各个点之记
                            db.SaveAs(pointMarkPalette.saveFileName & "TP" & num.ToString & ".dwg", DwgVersion.Current)
                            '提交事务处理
                            trans.Commit()
                        End Using

虽然你用的是C#,主要体会里面的方法就行了,我一直都用这个方法!

xgr 发表于 2012-9-26 15:32:39

好久没来啦,解决了,谢谢大家参与!
页: [1]
查看完整版本: 如何插入一个已定义于dwg之外的块