Technology Sharing

CAD secondary development (12) - Block definition and use

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Block is a very important knowledge point in CAD. Today I will classify and introduce some blocks, as well as define and reference them.

1. Concept

1.1 Block Definition

A block is a whole defined by multiple logically related graphic objects. The advantage is that it can unify the work standards and improve the work efficiency, because objects in life are not simply a unit, but may be composed of multiple units. Blocks can well represent this structure.

The essence of a block is a collection of entity objects stored in a block table record.

1.2 Attribute block definition

Attribute blocks are composed of entities and additional information (attributes). The definition of blocks in attribute blocks is the same as that of simple blocks, while the definition of attributes is mainly realized through the relevant properties and functions of the attribute's AttributeDefinition class. The specific implementations are:

  1. Instance of AttributeDefinition class and set the attribute value of the object;
  2. Since the attribute definition of a block can also be regarded as an entity in the block, the attribute definition can be appended to the block through the member function AppendEntity of the block table record class.

Among them, the attribute values ​​of the attribute definition mainly include:

  • The text's insertion point, height, rotation angle, alignment, and width;
  • Default values ​​for properties;
  • The mode of the property, such as Invisible, Constant, Verify, and Preset;
  • The attribute tag name.

1.3 Dynamic Block Definition

Dynamic blocks allow us to create blocks with high flexibility and customizability. Because once a traditional block is inserted into a drawing, its size, shape and position are usually fixed. Dynamic blocks are different. They can adjust their geometric properties through user interface interactions (such as dragging action handles) without redefining the entire block or manually editing its components.

1.4 Block Classification and Operation

Blocks are mainly divided into simple blocks, attribute blocks, and dynamic blocks. For blocks, there are mainly block definition operations, block reference operations (that is, block insertion operations), and block editing.

2. Block definition

2.1 Block Definition

Regardless of the block, their definitions are roughly the same (attribute blocks require adding attribute objects). The specific steps are as follows:

  1. Use the GetObject() function of the Transaction class to obtain the block table object;
  2. Create a BlockTableRecord object and set the block name;
  3. Create entity objects that make up the blocks;
  4. Call the AppendEntity function of the BlockTableRecord class to write the entities that make up the block into the block table record;
  5. Call the Add function of the BlockTable class to write the created block table record into the block table of the current graphic.

The specific code is as follows:

public static ObjectId AddBlockThroughDB(this Database db, string blockName, List<Entity> ents)
        {
            //声明ObjectId,用于返回
            ObjectId entId = ObjectId.Null;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForWrite);
                BlockTableRecord btr = new BlockTableRecord();
                btr.Name = blockName;
                for (int ii = 0; ii < ents.Count; ii++)
                {
                    Entity ent = ents[ii];
                    btr.AppendEntity(ent);
                }                    
                entId = bt.Add(btr);
                tr.AddNewlyCreatedDBObject(btr, true);
                tr.Commit();
            }
            return entId;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

2.2 Attribute Block Definition

The above is just a simple block definition. As for the attribute block, as the name implies, you need to define the attribute fields in the block (we can understand it as defining attribute variables, which need to be converted into specific variable values ​​when referenced).
Attribute block definition, we can add attributes to it by adding attributes.

		 /// <summary>
         /// 块添加属性
         /// </summary>
         /// <param name="blockId"></param>
         /// <param name="atts"></param>
         public static void AddAttsToBlocks(this ObjectId blockId, List<AttributeDefinition> atts)
         {
             Database db = blockId.Database;//获取数据库对象
             BlockTableRecord btr = blockId.GetObject(OpenMode.ForWrite) as BlockTableRecord;
             foreach (AttributeDefinition att in atts)
             {
                 btr.AppendEntity(att);
 
                 db.TransactionManager.AddNewlyCreatedDBObject(att, true);
             }
 
             btr.DowngradeOpen();
         }
 
         public static void AddAttsToBlocks(this ObjectId blockId, params AttributeDefinition[] atts)
         {
             blockId.AddAttsToBlocks(atts.ToList());
         }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Add attributes to the specified block definition. We can use it like this:

 		//属性添加
        AttributeDefinition attr1 = new AttributeDefinition(Point3d.Origin, "箱变", "箱变编号", "请输入箱变编号", ObjectId.Null);
        AttributeDefinition attr2 = new AttributeDefinition(Point3d.Origin + new Vector3d(0, 0.25, 0),
            "变电站", "变电站编号", "请输入变电站编号", ObjectId.Null);
            
       //然后将这两个属性加入到集合,再调用上面的方法即可。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

The parameters are described as follows:

  • Point3d position: This is the propertyDefined location, given in the form of three-dimensional coordinates. Even if your design works on a two-dimensional plane, you still need to provide a three-dimensional coordinate point, and the Z value is usually set to 0.
  • string value: This is the property definitiondefault valueWhen a block is inserted, this default value is used if no specific property value is provided.
  • string tag: This is the attribute definitionLabel, which is its unique identifier. When the block is inserted, the attribute value can be referenced and modified through this tag.
  • string prompt: This is the propertyTips, when the user needs to enter an attribute value when inserting a block, this prompt message will be displayed. If no user input is required, it can be left blank.
  • ObjectId style: This isThe object ID of the font styleIn AutoCAD, the font style determines the appearance of attribute text, including font, size, width ratio, etc. This parameter must be the ID of a valid font style object, otherwise an exception may be thrown.

2.3 Dynamic Block Definition

Dynamic block definition is based on the use of attribute blocksDynamicBlockReferencePropertyCollectionClasses impose constraints on attributes.

3. Blockquote (block insertion)

3.1 Normal Block Insertion

public void Insert()
{
    Database db = HostApplicationServices.WorkingDatabase;
    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
        BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForRead);
        BlockTableRecord space = db.CurrentSpaceId.GetObject(OpenMode.ForWrite) as BlockTableRecord;
        //判断名为“块1”的块是否存在
        if(! bt["块1"].IsNull)
        {
            BlockReference br = new BlockReference(Point3d.Origin, bt["块1"]);
            br.ScaleFactors = new Scale3d(2.0);//设置尺寸为原来2倍
            space.AppendEntity(br);
            trans.AddNewlyCreatedDBObject(br, true);

            trans.Commit();
        }
        else
        {
            return;
        }        
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

3.2 Attribute Block Insertion

The attribute entity in the block reference is represented by the AttibuteReference class in the DatabaseServices namespace. It is actually a single-line text object derived from the DBText class. The steps to add attributes to a block reference are as follows:

  1. Open the block table record object to which the block reference belongs;
  2. Loop through the entities in the block table record, and if the entity is an object defined by an attribute, set the attribute value for the block reference attribute object according to its identifier;
  3. Get the attribute collection object of the block reference object to add the newly created attribute reference object to the block reference. The attribute collection object is identified by the AttributeCollection property of BlockReference, and its AppendAttribute function can be called to complete the attribute addition of the block reference.
/// <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 InsertBlockrefence(this ObjectId spaceId, string layer, string blockName, Point3d postion, Scale3d scale, double rotateAngle, Dictionary<string, string> attNameValues)
         {
             // 获取数据库对象
             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]);
 
             br.ScaleFactors = scale;
 
             br.Layer = layer;
             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);
 
                     }
                 }
             }
             db.TransactionManager.AddNewlyCreatedDBObject(br, true);
             return br.ObjectId;//返回添加的快参照的ID
         }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

Some of the above parameters may not be necessary, such as the scaling and insertion ratio.

3.3 Attribute modification

/// <summary>
         /// 更新属性名称与取值
         /// </summary>
         /// <param name="blockRefId"></param>
         /// <param name="attNameValues"></param>
         public static void UpdateAttributesInBlock(this ObjectId blockRefId, Dictionary<string, string> attNameValues)
         {
             BlockReference blockRef = blockRefId.GetObject(OpenMode.ForRead) as BlockReference;
             if (blockRef != null)
             {
                 foreach (ObjectId id in blockRef.AttributeCollection)
                 {
                     AttributeReference attref = id.GetObject(OpenMode.ForRead) as AttributeReference;
                     if (attNameValues.ContainsKey(attref.Tag.ToUpper()))
                     {
                         attref.UpgradeOpen();
                         //设置属性值
                         attref.TextString = attNameValues[attref.Tag.ToUpper()].ToString();
 
                         attref.DowngradeOpen();
                     }
                 }
 
             }
 
         }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26