AutoCAD.net AttributeBlock实例3 炸属性块

本文介绍了AutoCAD.net中的AttributeBlock,解释了属性块的相关类如AttributeDefinition、AttributeReference、BlockReference和BlockTableRecord。属性块通过定义可修改的属性实现块的复用,常用于路线设计中的百米桩号。文章提供了一个炸开属性块的实例,以适应不同场景的需求。

1 AttributeBlock介绍

AttributeBlock这个名称并不存在于.net开发文档中,是我根据中文名称“属性块”直译的,可能不对,只是叫起来顺口。开发文档中与属性块相关的类有四个,分别是AttributeDefinition(属性定义)、AttributeReference(属性参照)、BlockReference(块参照)、BlockTableRecord(块)。如果一个BlockTableRecord包含了AttributeDefinition对象,则称为AttributeBlock。

其中AttributeDefinition、AttributeReference同属于DBText的子类,说明它们本质上是DBText,即单行文本,具有所有单行文本的特征,不同之处是它们的存储位置,AttributeDefinition要放入BlockTableRecord中,而AttributeReference要放入BlockReference的AttributeCollection中。

BlockReference父类为Entity,是众多实体(如DBText、Line)中的一员,代表对某个BlockTableRecord的引用,用户对BlockReference只能做平移、旋转、缩放的操作,而不能修改引用的内容,要修改只能对BlockTableRecord进行操作。如果在BlockTableRecord定义有AttributeDefinition,那么在BlockTableRecord的副本BlockReference中就可以修改AttributeDefinition的副本AttributeReference。

BlockReference、AttributeDefinition应放在不同的BlockTableRecord中,每个BlockTableRecord代表一个块,所有的BlockTableRecord都存储在BlockTable中。Record(记录)和Table(表)是构成关系型数据库的基本元素,关系型数据库一般由多个Table组成,每个Table又由多个Record组成。AutoCAD的数据存储文件(dwg文件)也叫图形数据库文件,是关系型数据库中较为复杂的一种。

dwg文件在新建时会初始化创建一些Table和Record,例如创建BlockTable(块表)、DimStyleTable(标注样式表)、TextStyleTable(文字样式表)、LayerTable(图层表)。每个表也会初始化一些Record,如BlockTable会默认新建ModelSpace、PaperSpace1、PaperSpace2这三个BlockTableRecord,分别代表“模型”、“布局1”、“布局2”选项卡。当我们在“模型”里面绘制直线、文字等实体后,程序会在BlockTable中查找名称为ModelSpace的BlockTableRecord,并向其中添加Entity实体。BlockTableRecord的父类为SymbolTableRecord。

AttributeReference对AttributeDefinition并不是引用的关系,虽然字面意思上是。AttributeDefinition对AttributeReference的某些属性进行了只读限制,如Constant、Preset、Verifiable、LockPositionInBlock这些属性只能在AttributeDefinition修改,而在AttributeReference是不能修改的。可以将AttributeDefinition比喻为一个模板,里面有一部分属性是不能修改的,还有一部分是可以修改的,这样才能保证AttributeReference的多样性,也是属性块的意义所在。

2 AttributeBlock实例

用属性块的好处是不用频繁定义块,我们只需要将块中需要改变的文字定义为属性,这样在插入块后可以对这些文字进行修改,使每个块都可以显示不同的文本。在路线设计中我们一般将百米桩号定义为属性块,块中文字表示相应位置的桩号,由于路线一般很长,桩号非常多,定义为属性块可以方便修改,但是在绘制桥型图的时候我们又需要将这些属性块炸开以方便调整比例。下面的实例展示了属性块的炸开。

3 主要代码

主要代码如下:

[CommandMethod("bat_zsk")]
public void Sub24()
{
    ObjectId[] ids = new ObjectId[] { };
    if (InputHelper.GetEntityIds(ref ids, "\n选择属性块", TypeValueHelper.Insert))
    {
        List<Entity> list = new List<Entity>();
        List<BlockReference> blockReferences = ids.Select(l => EntityHelper.GetEntityById(l) as BlockReference).ToList();
        foreach (var item in blockReferences)
        {
            list.AddRange(ExplodeBlockReference(item.Id));
            if (list.Count > 0) EntityHelper.DeleteById(item.Id);
        }
        EntityHelper.Post2CurrentSpace(list);
    }
}

/// <summary>
/// 分解块引用
/// </summary>
/// <param name="blockReferenceId"></param>
/// <returns></returns>
private List<Entity> ExplodeBlockReference(ObjectId blockReferenceId)
{
    List<Entity> ret = new List<Entity>();
    List<AttributeDefinition> attributeDefinitions = new List<AttributeDefinition>();
    BlockReference blockReference = EntityHelper.GetEntityById(blockReferenceId) as BlockReference;
    BlockTableRecord blockTableRecord = EntityHelper.GetSymbolTableRecordById(blockReference.BlockTableRecord) as BlockTableRecord;
    //如果块中有属性定义
    if (blockTableRecord.HasAttributeDefinitions)
    {
        DBObjectCollection dBObjectCollection = new DBObjectCollection();
        //分解BlockReference
        blockReference.Explode(dBObjectCollection);
        //删除AttributeDefinition,仅保留Entity
        foreach (var item in dBObjectCollection)
        {
            if (item is AttributeDefinition)
            {
                EntityHelper.DeleteById((item as AttributeDefinition).Id);
            }
            else if (item is Entity)
            {
                ret.Add(item as Entity);
            }
        }
        //将AttributeReference转为DBText
        foreach (ObjectId item in blockReference.AttributeCollection)
        {
            AttributeReference attributeReference = EntityHelper.GetEntityById(item) as AttributeReference;
            DBText dbText = new DBText();
            dbText.TextString = attributeReference.TextString;
            dbText.Position = attributeReference.Position;
            dbText.HorizontalMode = attributeReference.HorizontalMode;
            dbText.VerticalMode = attributeReference.VerticalMode;
            if (attributeReference.HorizontalMode != TextHorizontalMode.TextLeft ||
                attributeReference.VerticalMode != TextVerticalMode.TextBase ||
                attributeReference.Justify != AttachmentPoint.BaseLeft)
                dbText.AlignmentPoint = attributeReference.AlignmentPoint;
            dbText.Height = attributeReference.Height;
            dbText.WidthFactor = attributeReference.WidthFactor;
            dbText.Rotation = attributeReference.Rotation;
            dbText.TextStyleId = attributeReference.TextStyleId;
            dbText.LayerId = attributeReference.LayerId;
            dbText.ColorIndex = attributeReference.ColorIndex;
            dbText.SetDatabaseDefaults();
            dbText.AdjustAlignment(EntityHelper.GetActiveDatabase());
            ret.Add(dbText);
        }
    }
    else
    {
        MessageHelper.WriteMsg("\n非属性块不分解:" + blockTableRecord.Name);
    }
    return ret;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值