C#之CAD插入外部块文件

该博客介绍了如何在AutoCAD2018环境下使用C#编程将外部DWG文件中的命名块插入到当前图形中,并详细阐述了复制块、创建块参照以及设置动态属性的步骤。通过WblockCloneObjects方法实现块复制,利用BlockReference创建块参照,并通过AttributeReference处理块的属性定义。此外,还提供了处理动态属性值的方法。
摘要由CSDN通过智能技术生成

1、需求
插入外部文件中指定的块。

2、思路
将外部dwg文件加载到临时数据库中,把外部dwg文件中自定义的命名块复制到当前文档的数据库中;新建指定块的块参照加入到当前块表记录。

3、环境
AutoCAD 2018/vs2015

4、步骤:
(1) 新建一个临时图形数据库

Database tempDB = new Database(false, true);

(2) 调用Database类的 WblockCloneObjects()方法复制块

(3) 新建一个块参照:BlockReference

public BlockReference(Point3d position, ObjectId blockTableRecord);

(4) 把块参照添加到块表记录中

BlockTableRecord.AppendEntity()

Transaction.AddNewlyCreatedDBObject();

关键代码:

    /// <summary>
    /// 复制块文件
    /// </summary>
    /// <param name="TargetDB"></param>
    /// <param name="FileName">动态块文件路径</param>
    /// <param name="BlockName">动态块名称</param>
    /// <param name="Method"></param>
    public static void CopyBlockFromFile(this Database TargetDB, string FileName, string BlockName, DuplicateRecordCloning Method = DuplicateRecordCloning.Replace)
    {

        using (Database db = new Database(false, true))
        {
            db.ReadDwgFile(FileName, FileShare.ReadWrite, true, "");

            ObjectIdCollection ids = new ObjectIdCollection();
            ObjectIdCollection newoids = new ObjectIdCollection();
            IdMapping im = new IdMapping();

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, true, true);
                ids.Add(bt[BlockName]);

                tr.Commit();
            }
            try
            {
                //db.WblockCloneObjects(ids, TargetDB.BlockTableId, im, DuplicateRecordCloning.Ignore, true);
                db.WblockCloneObjects(ids, TargetDB.BlockTableId, im, DuplicateRecordCloning.Replace, false);
            }
            catch (Exception ex)
            {

            }
        }

    }

    /// <summary>
    /// 插入带属性的参照快(插入动态块)
    /// </summary>
    /// <param name="spaceId">空间的ID</param>
    /// <param name="layer">块要加入的图层名</param>
    /// <param name="blockName">快参照所属的快名</param>
    /// <param name="postion">插入点</param>
    /// <param name="scale">缩放比例</param>
    /// <param name="rotateAngle">旋转角度</param>
    /// <param name="attNameValues">属性名称与取值</param>
    /// <returns></returns>
    public static ObjectId InsertBlockrefenceModelSpace(this ObjectId spaceId, string blockName, Point3d postion, Scale3d scale, double rotateAngle, Dictionary<string, Dictionary<string, string>> attNameValues, Dictionary<string, Dictionary<string, string>> attDNameValues, bool isRoate = false)
    {
        // 获取数据库对象
        Database db = spaceId.Database;
        //以读的方式打开块表
        BlockTable bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
        //如果没有blockName d的块,则程序返回
        if (!bt.Has(blockName))

            return ObjectId.Null;//如果没有blockName的块,程序返回
        //以写的模式打开空间
        BlockTableRecord space = (BlockTableRecord)spaceId.GetObject(OpenMode.ForWrite);
        //获取块表的记录ID
        ObjectId btrId = bt[blockName];
        //打开块表记录
        BlockTableRecord record = btrId.GetObject(OpenMode.ForRead) as BlockTableRecord;

        //创建一个快参照并设置插入点
        BlockReference br = new BlockReference(postion, bt[blockName]);
        //DynamicBlockReferencePropertyCollection properties= br.DynamicBlockReferencePropertyCollection;            
        br.ScaleFactors = scale;
        br.Rotation = rotateAngle;
        space.AppendEntity(br);
        //判断块表记录是否包含属性定义
        if (record.HasAttributeDefinitions)
        {
            //若包含,则遍历属性定义
            foreach (ObjectId id in record)
            {
                //检查是否是属性定义
                AttributeDefinition attDef = id.GetObject(OpenMode.ForRead) as AttributeDefinition;
                if (attDef != null)
                {

                    //创建一个新的属性对象
                    AttributeReference attribute = new AttributeReference();
                    //从属性定义获取属性对象的对象特性
                    attribute.SetAttributeFromBlock(attDef, br.BlockTransform);
                    attribute.Rotation = attDef.Rotation;
                    attribute.Position = attDef.Position.TransformBy(br.BlockTransform);
                    attribute.AdjustAlignment(db);
                    //判断是否包含指定的属性名称
                    if (attNameValues.ContainsKey(attDef.Tag.ToUpper()))
                    {
                        //设置属性值
                        attribute.TextString = attNameValues[attDef.Tag.ToUpper()].ToString();
                    }
                    // 向块参照添加属性对象
                    br.AttributeCollection.AppendAttribute(attribute);
                    db.TransactionManager.AddNewlyCreatedDBObject(attribute, true);

                }
            }
        }
        if (isRoate )
        {
            br.TransformBy(Matrix3d.Rotation(GeTools.DegreeToRadian(180), Vector3d.YAxis, postion));
        }
        ChangeDynamicValue(br, attDNameValues);
        db.TransactionManager.AddNewlyCreatedDBObject(br, true);
        return br.ObjectId;//返回添加的快参照的ID
    }

说明:
Dictionary<string, Dictionary<string, string>> : Dictionary<属性设置值, Dictionary<属性名称, 类型(string\double)>>

   /// <summary>
    ///设置自定义属性值
    /// </summary>
    /// <param name="br"></param>
    /// <param name="attDNameValues"></param>
public static void ChangeDynamicValue(BlockReference br, Dictionary<string, Dictionary<string,string>> attDNameValues)
    {
        if (br != null && br.IsDynamicBlock)
        {
            DynamicBlockReferencePropertyCollection pc = br.DynamicBlockReferencePropertyCollection;
            AttributeCollection ar = br.AttributeCollection;

            foreach (DynamicBlockReferenceProperty prop in pc)
            {
                if (attDNameValues.Keys.Contains(prop.PropertyName) && !prop.ReadOnly)
                {
                    try
                    {
                        Dictionary<string, string> dic = attDNameValues[prop.PropertyName];
                        List<string> values = dic.Keys.ToList();
                        List<string> types = dic.Values.ToList();
                        switch(types[0].ToLower()) 
                        {
                            case "double":
                                string[] sp = prop.PropertyName.Split('_');
                                if (sp != null)
                                {
                                    //if(sp[sp.Length-1]=="mm")
                                    //    prop.Value = double.Parse(values[0])/1000;
                                    //else
                                        prop.Value = double.Parse(values[0]);
                                }
                                break;
                            case "string":
                                prop.Value = values[0];
                                break;
                        }
                        //prop.Value = attDNameValues[prop.PropertyName];
                       
                    }
                    catch (System.Exception ex)
                    {
                       
                    }
                }                   
                else
                {
                    continue;
                }

            }
        }

    }
  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值