6.块参照(BlockReference)

愿你出走半生,归来仍是少年! 

环境:.NET FrameWork4.5、ObjectArx 2016 64bit、Entity Framework 6. 

         在CAD中针对点的符号化通常使用块引用进行表达,在CAD中的对应Insert实体,在开发中对应的类为BlockReference

1. 普通块引用的插入 

        所谓的普通块引用就是未带属性的块,熟悉CAD的应知道在CAD中的块对象是可以包含属性定义的。通过包含属性定义的块定义构造的块引用,也会包含对应的属性,并可以自行维护。

        此处的参数“defineName”是在当前文档中的块定义的名称,当文档中包含此块定义时,块引用的插入才可能正常的完成。如何插入块定义,请点击进入传送门

 public static void InsertBlockReference(this string defineName,   Point3d position,string layerName)
        {
            try
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;

               Database db = doc.Database;

                using (Transaction trans = doc.Database.TransactionManager.StartTransaction())
                {

                    //当前文档块表
                    BlockTable blockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

                    //块表中存在该块表记录, 并且没有被删除
                    if (blockTable.Has(defineName) && !blockTable[defineName].IsErased)
                    {

                        ObjectId defineId = blockTable[defineName];

                        //模型空间
                        var mdlSpc = trans.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                        //新建块参照
                        BlockReference blockReference = new BlockReference(position, defineId);
                        //图层名称
                        blockReference.Layer = layerName;

                        //在模型空间中追加此块参照
                        mdlSpc.AppendEntity(blockReference);
                        trans.AddNewlyCreatedDBObject(blockReference, true);

                   
                        
                        trans.Commit();
                    }
                }
               


            }
            catch (Exception ex)
            {

                throw;
            }
        }

 2. 属性块引用的插入 

       属性块的插入相较于普通块的插入,多了属性实体这部分。因此在插入过程中应当对块内的属性进行维护。

        需要根据块定义获取是否存在属性定义,若存在进行属性定义的遍历。根据属性定义给块参照插入对应的属性参照。

 /// <summary>
        /// 插入块引用
        /// </summary>
        /// <param name="defineName">块定义名称</param>
        /// <param name="position">插入点</param>
        /// <param name="layerName">要插入的图层名称</param>
        /// <param name="vals">属性值,不是属性块可直接设置null</param>
        public static void InsertBlockReference(this string defineName, Point3d position,string layerName, Dictionary<string, string> vals)
        {
            try
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;

               Database db = doc.Database;
                using (DocumentLock acLckDoc = doc.LockDocument())
                {
                    using (Transaction trans = doc.Database.TransactionManager.StartTransaction())
                    {

                        //当前文档块表
                        BlockTable blockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

                        //块表中存在该块表记录, 并且没有被删除
                        if (blockTable.Has(defineName) && !blockTable[defineName].IsErased)
                        {
                            //获取块定义的ID
                            ObjectId defineId = blockTable[defineName];

                            //获取块定义对象
                            BlockTableRecord defineObject = trans.GetObject(defineId, OpenMode.ForWrite) as BlockTableRecord;

                            //模型空间
                            var mdlSpc = trans.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                            //新建块参照
                            BlockReference blockReference = new BlockReference(position, defineId);

                            //图层名称
                            blockReference.Layer = layerName;

                            //在模型空间中追加此块参照
                            mdlSpc.AppendEntity(blockReference);
                            trans.AddNewlyCreatedDBObject(blockReference, true);

                            if (vals != null)
                            {
                                //判断是否有属性定义,进行属性处理
                                if (defineObject.HasAttributeDefinitions)
                                {
                                    //遍历块定义下的实体(属性定义也是实体)
                                    foreach (var childId in defineObject)
                                    {
                                        //获取实体
                                        var childEntity = trans.GetObject(childId, OpenMode.ForRead);

                                        //判断是否为属性定义
                                        if (childEntity is AttributeDefinition attDefine)
                                        {
                                            using (AttributeReference attRef = new AttributeReference())
                                            {
                                                attRef.SetAttributeFromBlock(attDefine, blockReference.BlockTransform);

                                                attRef.Position = attDefine.Position.TransformBy(blockReference.BlockTransform);

                                                attRef.Rotation = attDefine.Rotation;

                                                //判断是否包含了指定的属性名称
                                                if (vals.ContainsKey(attRef.Tag.ToUpper()))
                                                {
                                                    //设置属性值
                                                    attRef.TextString = vals[attRef.Tag.ToUpper()].ToString();
                                                }

                                                blockReference.AttributeCollection.AppendAttribute(attRef);
                                                trans.AddNewlyCreatedDBObject(attRef, true);
                                            }

                                        }
                                    }
                                }

                            }




                        }

                        trans.Commit();
                    }

                }

            }
            catch (Exception ex)
            {

                throw;
            }
        }

 3. 块参照的移动 

       在实际的生产需求中,存在将块的位置进行变更的情况,即将块从点1移动到点2。通常的做法为直接给块设定新的位置。但是当块中存在属性参照的时候这个直接设定新位置的方式显然就行不通了,此时我们可通过点2相较于点1的偏移进行移动整个块参照,包括它的属性参照。

/// <summary>
        /// 平移块
        /// </summary>
        /// <param name="br"></param>
        /// <param name="trans"></param>
        /// <param name="offset">平移量</param>
        public static void Move(this BlockReference br, Transaction trans, Point3d offset)
        {
            try
            {
                br.UpgradeOpen();

                br.Position = new Point3d(
                        br.Position.X + offset.X,
                        br.Position.Y + offset.Y,
                        br.Position.Z + offset.Z
                    );

                br.DowngradeOpen();

                var ids = br.AttributeCollection;

                foreach (ObjectId tempId in ids)
                {


                    var attrRef = (AttributeReference)trans.GetObject(tempId, OpenMode.ForWrite, false, true);

          

                    if (attrRef.Justify == AttachmentPoint.BaseLeft)
                    {

                        //左对齐时变更属性的位置
                        attrRef.Position = new Point3d(
                                                attrRef.Position.X + offset.X,
                                                attrRef.Position.Y + offset.Y,
                                                attrRef.Position.Z + offset.Z
                                            );
                    }
                    else {
                        //非左对齐时,变更属性的对齐点
                        attrRef.AlignmentPoint= new Point3d(
                                                attrRef.AlignmentPoint.X + offset.X,
                                                attrRef.AlignmentPoint.Y + offset.Y,
                                                attrRef.AlignmentPoint.Z + offset.Z
                                            );
                    }



                } 
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

 4. 块参照的块定义变更

       在Gis中可以通过不同的符号表格一个点,CAD中通过块参照可以表达一个点对象,通过其块定义进行不同的符号化。每个块参照在创建的时候都需要设定一个对应的块定义对象。通过改变块参照的块定义可实现符号化的变更。

      /// <summary>
        /// 变更块定义
        /// </summary>
        /// <param name="bf"></param>
        /// <param name="defindId">块定义id</param>
        public static void ChangeDefine(this BlockReference bf, ObjectId defindId)
        {
            try
            {
                if (defindId.IsErased || !defindId.IsValid)
                {
                    return;
                }

                bf.UpgradeOpen();
                 
                bf.BlockTableRecord = defindId;

                bf.DowngradeOpen();


            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就是那个帕吉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值