技術共有

CAD二次開発(12) - ブロックの定義と使い方

2024-07-12

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

ブロックは CAD において非常に重要な知識ポイントです。今日は、ブロックの分類と紹介、およびブロックの定義と参照について説明します。

1.コンセプト

1.1 ブロックの定義

ブロックは、論理的に関連する複数のグラフィック オブジェクトによって定義されるエンティティです。利点は、生活のオブジェクトは単純な単位ではなく、複数の単位で構成される場合があるため、この構造をうまく表現できるため、作業基準を統一し、作業効率を向上できることです。

ブロックの本質は、ブロック テーブル レコードに格納されているエンティティ オブジェクトのコレクションです。

1.2 プロパティブロックの定義

属性ブロックは、エンティティと追加情報 (属性) で構成されます。属性ブロックのブロックの定義は、単純なブロックの定義と同じであり、属性の定義は主に AttributeDefinition クラスの関連する属性と関数によって実現されます。 。具体的な実装には以下が含まれます。

  1. AttributeDefinition クラスのインスタンスであり、オブジェクトの属性値を設定します。
  2. ブロックの属性定義もブロック内の実体とみなすことができるため、ブロックテーブルレコードクラスのメンバ関数AppendEntityを通じて属性定義をブロックに付加することができる。

その中で、属性によって定義される属性値には主に次のようなものがあります。

  • テキストの挿入ポイント、高さ、回転角度、配置および幅。
  • 属性のデフォルト値。
  • 属性モード (不可視モード、Invisible モード、定数モード、定数モード、検証モード、Verify モード、プリセット モード、Preset など)。
  • 属性タグ名。

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 属性ブロックの挿入

ブロック参照の属性エンティティは、DatabaseServices 名前空間の AttibuteReference クラスによって表されます。これは、実際には DBText クラスから派生した単一行のテキスト オブジェクトです。ブロック参照に属性を追加するには、次の手順に従います。

  1. ブロック参照が属するブロック テーブル レコード オブジェクトを開きます。
  2. ブロック テーブル レコード内のエンティティをループします。エンティティが属性によって定義されたオブジェクトの場合は、その識別に従ってブロック参照属性オブジェクトの属性値を設定します。
  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