기술나눔

CAD 2차 개발(12) - 블록 정의 및 사용

2024-07-12

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

블록은 CAD에서 매우 중요한 지식 포인트입니다. 오늘은 블록의 분류와 소개, 블록의 정의와 참조에 대해 설명하겠습니다.

1. 컨셉

1.1 블록 정의

블록은 논리적으로 관련된 여러 그래픽 객체로 정의되는 엔터티입니다. 생활 속의 사물은 단순한 단위가 아니라 여러 개의 단위로 구성될 수 있기 때문에 업무표준을 통일하고 업무 효율성을 높일 수 있다는 장점이 있다.

블록의 본질은 블록 테이블 레코드에 저장된 엔터티 객체의 모음입니다.

1.2 속성 블록 정의

속성 블록은 구성된 엔터티와 추가 정보(속성)로 구성되며, 속성 블록의 블록 정의는 단순 블록과 동일하며, 속성의 정의는 주로 해당 속성의 AttributeDefinition의 관련 속성 및 기능을 통해 이루어진다. 수업. . 구체적인 구현에는 다음이 포함됩니다.

  1. AttributeDefinition 클래스의 인스턴스이며 객체의 속성 값을 설정합니다.
  2. 블록의 속성 정의도 블록의 엔터티로 간주될 수 있으므로 블록 테이블 레코드 클래스의 AppendEntity 멤버 함수를 통해 속성 정의를 블록에 첨부할 수 있습니다.

그 중 속성으로 정의되는 속성값은 주로 다음과 같습니다.

  • 텍스트의 삽입점, 높이, 회전 각도, 정렬 및 너비.
  • 속성의 기본값입니다.
  • 보이지 않는 모드, 보이지 않는 모드, 상수 모드, 상수 모드, 검증 모드, 검증 모드 및 사전 설정 모드와 같은 속성 모드, 사전 설정;
  • 속성 태그 이름.

1.3 동적 블록 정의

동적 블록을 사용하면 높은 수준의 유연성과 사용자 정의 가능성을 갖춘 블록을 만들 수 있습니다. 기존 블록을 도면에 삽입하면 일반적으로 크기, 모양 및 위치가 고정됩니다. 반면 동적 블록은 전체 블록을 다시 정의하거나 해당 구성요소를 수동으로 편집할 필요 없이 사용자 인터페이스 상호 작용(예: 동작 핸들 끌기)을 통해 기하학적 특성을 조정할 수 있습니다.

1.4 블록 분류 및 운영

블록은 크게 단순블록, 속성블록, 동적블록으로 구분된다. 블록의 경우 주로 블록 정의 작업, 블록 참조 작업(즉, 블록 삽입 작업) 및 블록 편집이 있습니다.

2. 블록 정의

2.1 블록 정의

블록 종류에 관계없이 정의는 거의 동일합니다(속성 블록은 속성 객체를 추가해야 함). 구체적인 단계는 다음과 같습니다.

  1. 블록 테이블 객체를 얻으려면 Transaction 클래스의 GetObject() 함수를 사용하십시오.
  2. BlockTableRecord 객체를 생성하고 블록 이름을 설정합니다.
  3. 블록을 구성하는 엔터티 개체를 만듭니다.
  4. BlockTableRecord 클래스의 AppendEntity 함수를 호출하여 블록을 구성하는 엔터티를 블록 테이블 레코드에 씁니다.
  5. BlockTable 클래스의 Add 기능을 호출하여 생성된 블록 테이블 레코드를 현재 도면의 블록 테이블에 씁니다.

구체적인 코드는 다음과 같습니다.

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 속성 블록 정의

위는 단순한 블록에 대한 정의일 뿐입니다. 속성 블록의 경우 이름에서 알 수 있듯이 블록에 속성 필드를 정의해야 합니다. (특정 변수 값으로 변환해야 하는 속성 변수를 정의하는 것으로 이해할 수 있습니다.) ​참조할 때).
속성 블록 정의에 속성을 추가하여 속성을 추가할 수 있습니다.

		 /// <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

지정된 블록 정의에 속성을 추가합니다. 우리는 이것을 다음과 같이 사용할 수 있습니다:

 		//属性添加
        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

매개변수 설명은 다음과 같습니다:

  • Point3d 위치: 이것이 속성입니다.정의된 위치 , 3차원 좌표의 형태로 주어진다. 디자인이 2차원 평면에서 작업되더라도 3차원 좌표점을 제공해야 하며, Z 값은 일반적으로 0으로 설정됩니다.
  • 문자열 값: 이는 속성에 의해 정의됩니다.기본값 . 블록을 삽입할 때 특정 속성 값이 제공되지 않으면 이 기본값이 사용됩니다.
  • 문자열 태그: 이는 속성에 의해 정의됩니다.상표 , 이는 고유 식별자입니다. 블록 삽입 시 이 태그를 통해 속성값을 참조하고 수정할 수 있습니다.
  • 문자열 프롬프트: 이것은 속성입니다프롬프트 메시지 , 사용자가 블록을 삽입할 때 속성값을 입력해야 하는 경우 이 프롬프트 메시지가 표시됩니다. 사용자 입력이 필요하지 않은 경우 공백으로 둘 수 있습니다.
  • ObjectId 스타일: 이것은글꼴 스타일의 개체 ID . AutoCAD에서 글꼴 스타일은 글꼴, 크기, 너비 비율 등을 포함한 속성 문자의 모양을 결정합니다. 이 매개변수는 유효한 글꼴 스타일 객체의 ID여야 합니다. 그렇지 않으면 예외가 발생할 수 있습니다.

2.3 동적 블록 정의

동적 블록을 정의하려면 속성 블록을 사용해야 합니다.DynamicBlockReferencePropertyCollection클래스는 속성에 제약을 가합니다.

3. 블록 참조(블록 삽입)

3.1 일반 블록 삽입

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 속성 블록 삽입

블록 참조의 속성 엔터티는 실제로 DBText 클래스에서 파생된 한 줄 텍스트 개체인 DatabaseServices 네임스페이스의 AttibuteReference 클래스로 표시됩니다. 블록 참조에 속성을 추가하려면 다음 단계를 따르십시오.

  1. 블록 참조가 속한 블록 테이블 레코드 객체를 엽니다.
  2. 블록 테이블 레코드의 엔터티를 반복합니다. 엔터티가 속성에 의해 정의된 객체인 경우 해당 ID에 따라 블록 참조 속성 객체의 속성 값을 설정합니다.
  3. 새로 생성된 속성 참조 객체를 블록 참조에 추가하려면 블록 참조 객체의 속성 컬렉션 객체를 가져옵니다. 속성 컬렉션 객체는 BlockReference의 AttributeCollection 속성으로 식별되며 해당 AppendAttribute 함수를 호출하면 블록 참조의 속성 추가를 완료할 수 있습니다.
/// <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

위의 매개변수 중 스케일링 비율, 삽입 비율 등 일부 매개변수는 필요하지 않을 수 있습니다.

3.3 속성 수정

/// <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