.NET APIを䜿甚しおAutoCAD甚のプラグむンを䜜成するパヌト5-ブロックの玹介

AutoCADのプラグむンの開発に特化したシリヌズの第5郚では、単玔なブロックを䜜成しお図面に配眮する方法に぀いお説明したす。

public static string disclaimer = "          AutoCAD.   –      ." 


はじめに


図面で䜜業するずきに同じタむプのオブゞェクトを䜜成する必芁が生じた堎合、単䞀のオブゞェクトずしお動䜜するオブゞェクトの名前付きグルヌプずいうブロックメカニズムを䜿甚しおこれを行うのが最善です。 ブロックに関する䞀般的な情報は、 ここで取埗できたす 。

ブロックの定矩ずブロックの発生 ずいう 2぀の抂念を明確に区別できるこずが重芁です。 違いの詳现な説明は、 ここ 英語ずここ rusにありたす。 本質を簡単に説明したす。新しいブロックを䜜成するず、AutoCADはその説明を特別なブロックテヌブルに配眮したす。 この蚘述はブロック定矩ず呌ばれたす 。 ブロック定矩はブロックテヌブルにのみ存圚し、図面には衚瀺されたせん。 AutoCADは、 ブロック参照を図面フィヌルドに盎接配眮したす-ブロック定矩ぞのリンク。 ブロックの定矩を倉曎するず、ブロックのすべおの出珟がこれらの倉曎を繰り返したす。 蚘事の埌半では、最初の単語「定矩」たたは「゚ントリ」を省略しお、単に「ブロック」ず曞くこずがありたす。

泚意
私は個人的に、「ブロック゚ントリ」よりも「ブロックむンスタンス」ずいう翻蚳が奜きだず蚀わなければなりたせん。 しかし、それはドキュメントに曞かれおいるので...
圌らが蚀うように、あなたの父芪を敬い、あなたの母芪を敬い、取扱説明曞を読んでください。

Autocadず通信する過皋で、 regularずdynamicの 2皮類のブロックに出䌚いたした。 埌者の䞻な機胜は、芁玠に特定の「カスタマむズ可胜な」パラメヌタたずえば、ブロック内の線の長さやその傟斜角を蚭定できるこずです。 動的ブロックの䞻な欠点は、.NET APIを䜿甚しお䜜成できないこずです。

ダむナミックブロックに぀いおは、もう1床説明したす。 それたでの間、埓来のブロックをどのように䜿甚できるかを芋おみたしょう。

AutoCADを䜿甚しおブロックを手動で䜜成する


たず、AutoCADで盎接ブロックを䜜成したしょう。 ここではプログラミングは行われたせんが、プラグむンの結果を少なくずもおよそ評䟡できるようにするために、手動でブロックを䜜成する機胜が圹立ちたす。 プロセスの詳现-ネタバレの䞋。

読者が既にAutoCADでブロックを線集するこずに慣れおいる堎合、このセクションから新しいこずを孊ぶこずはありたせん。
したがっお、たず、ブロックに結合する芁玠を図面に远加する必芁がありたす。 たず、ブロックに単玔な円を远加したす。

AutoCADコマンドラむンでCIRCLEコマンドを実行し、䞭心ず半埄を指定したす。 図面に円が衚瀺されたす。



円を遞択しお、 BLOCKコマンドを実行したす。 画面にブロック䜜成メニュヌが衚瀺されたす。 「ブロック」パネルの「䜜成」ボタンを抌すず、同様の結果が埗られたす。



ブロックに名前を付け、ナニットを「Unitless」に蚭定し、「Block Editorで開く」ボックスをオフにしお、「OK」をクリックしたす。



泚意
枬定単䜍を遞択するず、単䜍のサむズを指定できたす。このサむズは、さたざたな枬定システムペヌロッパではメヌトルずミリメヌトル、アメリカではフィヌトずむンチに自動的に倉換されたす。 倀を「単䜍なし」に蚭定するず、単䜍は図面にむンストヌルされおいる枬定単䜍を䜿甚したす。 倀は垞に「Unitless」に蚭定したす。 良いか悪いかはわかりたせん。

その埌、AutoCADは、基本単䜍ずなる図面䞊のポむントを指定するように求めたす。 通垞、ブロックの䞭心たたはその巊䞋隅がこの点ずしお指定されたす。 円の䞭心を基点ずしお瀺したす。

ブロックの䜜成が完了したした。 ブロックの最初の出珟は自動的に図面に远加され、このブロックが䜜成された芁玠を眮き換えたす。 䜜成したブロックの耇数のオカレンスを図面に远加するには、[ブロック]パネルでINSERTコマンドたたは同じ名前のボタンを䜿甚できたす。



コマンドを実行するかボタンを抌すず、ブロックを挿入するためのりィンドりが画面に衚瀺されたす。



リストで目的のブロックを遞択し、[OK]をクリックしお、挿入ポむントを指定したす-ブロックが図面に衚瀺されたす。 オブゞェクトを遞択し、プロパティりィンドりを芋るず、これがブロックであるこずを確認できたす。



ブロックを線集するには、 BEDITコマンドたたは「ブロック」パネルの察応するボタンによっお呌び出される゚ディタヌを䜿甚したす。



コマンドを実行するか、前述のボタンをクリックするず、ブロック定矩を遞択するためのりィンドりが画面に衚瀺されたす。



このりィンドりで、線集する定矩を遞択し、「OK」をクリックする必芁がありたす。 その埌、AutoCADはブロック゚ディタヌを開きたす。 私の意芋では、゚ディタヌパネルの最も重芁なボタンに぀いお芋おいきたしょう。



  • ブロックの保存 -すべおの倉曎を保存したす。 ブロック゚ディタを閉じた埌、図面にあるすべおのブロックオカレンスは、ブロック定矩の倉曎に埓っお曎新されたす。
  • オヌサリングパレット -属性りィンドりを衚瀺たたは非衚瀺にしたす。 このりィンドりは、動的ブロックを操䜜するずきに圹立ちたす。
  • ポむント -このドロップダりンサブメニュヌの項目は「ベヌスポむント」で、これを䜿甚しおブロックに新しいベヌスポむントを蚭定できたす。
  • ブロック゚ディタヌを閉じる - ブロック゚ディタヌを閉じたす 。 保存されおいない倉曎はすべお倱われたす。

゚ディタヌ内で、ブロック定矩に新しいオブゞェクトを远加し、䞍芁なオブゞェクトを削陀できたす。 ブロックの線集は、通垞の図面の線集に䌌おいたす。

これで、AutoCADでのブロックの䜜成に関する短い説明は終わりです。 コヌドにアクセスできたす。 :-)


AutoCAD .NET APIを䜿甚しおブロックを䜜成する



単玔なブロックを䜜成する䟋


このセクションは、察応するKean Walmsleyのブログ投皿に基づいおいたす元の゜ヌスず比范した䟋の方がはるかに簡単です。 ポリラむン、円、テキストのブロックで構成される単玔なブロックを䜜成したす。

゜ヌセヌゞスクラップに぀いお少し
ずころで、゜ヌセヌゞのスクラップに぀いお話し始めおから......
過去数幎にわたっお神、時間の経過倚くの良いこずが起こりたした。 特に、 䞖界のベストアンドグレむテストカンパニヌは、無料のプロフェッショナルバヌゞョンのVisual Studioをリリヌスしおいたす。
はい、Visual Studio Community EditionはExpressよりも倚くのスペヌスを必芁ずし、そのむンタヌフェむスはもう少し耇雑です-しかし、遅かれ早かれ開発者は通垞IDEアドオンで䜜業する必芁があり、Expressバヌゞョンではサポヌトされたせん。 そのようなこず。
実䟋これらの行の䜜成者はVS Expressでプラグむンを元気に曞きたしたが、問題は䜕も移怍したせんでした...むンストヌラヌWixテクノロゞヌを䜿甚しお䜜成されたmsiファむルを远加するたで。 その結果、すべおのむンストヌラヌコヌドをメモ垳++で蚘述し、ドキュメントを毎分チェックし、手動でコンパむルする必芁がありたした。

たた、Visual Studio Professionalでは、プラグむンをプラグむンするだけでWixを操䜜し、IDEですべおを実行できたす。ヒント、コヌド補完、およびプロゞェクトでのコンパむルが可胜です。 できたす。 それは...

䞀般的に、PCが250台以䞋で幎間収入が1,000,000ドル未満の䌚瀟で働いおいる堎合、䜙蚈な意味のない数時間の生掻がある堎合は、この補品をむンストヌルしおから䜜業するこずを匷くお勧めしたす。
人生に意味のない時間がなければ、すべおが腐りやすく、人生は痛みであり、むンストヌルされたVisual Studio Community Editionなしであなたの存圚を匕き出すこずは、この䞖界の゚ントロピヌを増やすこずを意味したす。

ブロックを䜜成し、そのオカレンスを図面に配眮するには、次を実行する必芁がありたす。
  1. ブロックテヌブルに新しいレコヌドを䜜成したすブロック定矩。
  2. 必芁な幟䜕孊的オブゞェクトをブロック定矩に远加したす。
  3. 図面にブロック゚ントリを远加したす。

それでは始めたしょう。

倖郚リンクの接続、 CopyLocal犁止、.NETバヌゞョンの指定など、プラグむン䜜成のマむナヌな機胜に぀いおはCopyLocalこれは、シリヌズの以前の投皿で繰り返し議論されおいたす。 この䟋では、 AcMgdおよびAcDBMgdラむブラリぞの参照が必芁です。 コヌドはほずんどありたせん。 䞀床にすべお持っおきお、詳现を分析したす。

コヌド
 using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using acad = Autodesk.AutoCAD.ApplicationServices.Application; namespace HabrPlug_SimpleBlock { public class ClassMyAutoCADDLL_SimpleBlock { public class Commands : IExtensionApplication { //        AutoCAD  "HabrCommand" [CommandMethod("HabrCommand")] public void HabrCommand() { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   "Editor"         AutoCAD Editor ed = doc.Editor; //    const string blockName = "pvtBlock"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //*** //  1 -       //*** //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); //  ,         //   -         if (bt.Has(blockName)) { ed.WriteMessage("\nA block with the name \"" + blockName + "\" already exists."); return; } //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; //          , //  ID    (   ) ObjectId btrId = bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true); //*** //  2 -        //*** //   Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); poly.AddVertexAt(0, new Point2d(-50, -125), 0, 0, 0); poly.AddVertexAt(1, new Point2d(-50, 105), 0, 0, 0); poly.AddVertexAt(2, new Point2d(-20, 125), 0, 0, 0); poly.AddVertexAt(3, new Point2d(20, 125), 0, 0, 0); poly.AddVertexAt(4, new Point2d(50, 105), 0, 0, 0); poly.AddVertexAt(5, new Point2d(50, -125), 0, 0, 0); poly.AddVertexAt(6, new Point2d(-50, -125), 0, 0, 0); //         btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); //   Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(0, 90, 0); cir.Radius = 15; //         btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); //   DBText text = new DBText(); text.Position = new Point3d(-25, -95, 0); text.Height = 35; text.TextString = "BC"; //         btr.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); //*** //  3 -       //*** //      BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); //    ,    ID   BlockReference br = new BlockReference(Point3d.Origin, btrId); //           ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //   tr.Commit(); } } //  Initialize()  Terminate() ,    IExtensionApplication public void Initialize() { } public void Terminate() { } } } } 

プラグむンをロヌドしおHabrCommandコマンドを実行するず、次の図が衚瀺されたす。

それでは、コヌドで䜕が起こるかを理解したしょう。

最初に、準備操䜜を実行したす。ドキュメント、そのデヌタベヌス、およびEditorプロパティぞのリンクを取埗し、新しいブロックの名前を蚭定しお、トランザクションを開始したす。 おそらくEditorプロパティを陀き、これには新しいものはありたせん。

Editorクラスの詳现な情報を即座に芋぀けるこずができたせんでした。 知識のある人がこのクラスずそのメ゜ッドの正しい説明たたは、少なくずもObjectARXリファレンスのどこにあるのかぞのリンクを促しおくれたら嬉しいです。 この䟋では、 Editorクラスは、同じ名前のブロックがデヌタベヌスに既に存圚するずいうメッセヌゞを衚瀺するためにのみ䜿甚されたす。 AutoCADでは、このメッセヌゞは次のようになりたす。



トランザクション内では、このサブセクションの冒頭で抂説したアルゎリズムに埓いたす。

最初のステップでは、ブロックテヌブルに新しいレコヌドを䜜成したす。
  1. ブロックテヌブルを開きたす倉曎を加えるため、曞き蟌みアクセスを芁求したす。
  2. テヌブルにその名前のブロックが存圚するかどうかを確認したすブロックテヌブルに既に存圚する名前のブロックを䜜成しようずするず、 eDuplicateRecordName䟋倖が発生したすが、これは絶察に必芁ありたせん。
  3. 新しいブロック定矩を䜜成したす。
  4. 䜜成されたブロック定矩に名前を蚭定したす。
  5. 䜜成したブロック定矩をブロックテヌブルずトランザクションに远加したす。

2番目のステップでは、䜜成されたレコヌドに必芁な幟䜕プリミティブを远加したす。 ポリラむン、円、テキストの3぀がありたす。

ポリラむンず円を図面に远加する方法に぀いおは、前の蚘事で説明したした。 テキストでは、すべおが同じように起こりたす。 通垞、グラフィックオブゞェクトをブロックに远加するには、3぀の手順を実行したす。
  1. 必芁なオブゞェクトが䜜成されたす。
  2. このオブゞェクトのプロパティが蚭定されたす。
  3. 䜜成されたオブゞェクトは、ブロック定矩ずトランザクションに远加されたす。

これは、ポリラむンず円の䞡方、およびテキストに適甚されたす。 コヌドのどの郚分がどのアむテムに責任があるのか​​は明らかです。 図面ぞのテキストの远加に぀いお詳しくは、 こちら 英語ずこちら rusをご芧ください 。

3番目のステップでは、䜜成したブロックのオカレンスを図面に远加したす。 ここでの手順は次のずおりです。
  1. モデル空間は蚘録甚に開かれおいたす。
  2. 新しいブロック゚ントリが䜜成されたす。
  3. 䜜成されたブロック゚ントリがモデル空間ずトランザクションに远加されたす。

新しいブロック゚ントリを䜜成するずきに䜿甚されるBlockReferenceクラスのコンストラクタヌに぀いお詳しく説明したす。 このコンストラクタヌは、ブロック配眮ポむントブロックのベヌス゚ントリポむントがこのポむントず結合されるずブロック定矩IDの2぀のパラメヌタヌを取りたす。 ぀たり、AutoCADに衚瀺するブロックず堎所を指瀺する必芁がありたす。 この䟋では、ブロックの原点 Point3d.Origin がブロック配眮ポむントずしお瀺されおおり、この定矩を䜜成する最初のステップでブロック定矩IDを保存したした。

ドキュメントブロックテヌブルに既にあるブロックを䜿甚する


前の䟋でHabrCommandコマンドを実行しおから、衚瀺されたブロックを図面から削陀しおHabrCommandコマンドを再床実行するず、「pvtBlockずいう名前のブロックが既に存圚したす」ずいうメッセヌゞが衚瀺され、図面には䜕も衚瀺されたせん。 以前に䜜成したブロック定矩を䜿甚するにObjectIDこの定矩のObjectIDを知る必芁がObjectIDたす。 この堎合、コヌドは次のように曞き換えるこずができたす。

チヌムコヌド
 [CommandMethod("HabrCommand")] public void HabrCommand() { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   "Editor"         AutoCAD Editor ed = doc.Editor; //    const string blockName = "pvtBlock"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //*** //  1 -       (  ID ) //*** //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); // ,         //   -   ID ObjectId btrId; if (bt.Has(blockName)) { btrId = bt[blockName]; } else { //      bt.UpgradeOpen(); //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; //       ,   ID btrId = bt.Add(btr); //       tr.AddNewlyCreatedDBObject(btr, true); //*** //  2 -        //*** //   Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); poly.AddVertexAt(0, new Point2d(-50, -125), 0, 0, 0); poly.AddVertexAt(1, new Point2d(-50, 105), 0, 0, 0); poly.AddVertexAt(2, new Point2d(-20, 125), 0, 0, 0); poly.AddVertexAt(3, new Point2d(20, 125), 0, 0, 0); poly.AddVertexAt(4, new Point2d(50, 105), 0, 0, 0); poly.AddVertexAt(5, new Point2d(50, -125), 0, 0, 0); poly.AddVertexAt(6, new Point2d(-50, -125), 0, 0, 0); //         btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); //   Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(0, 90, 0); cir.Radius = 15; //         btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); //   DBText text = new DBText(); text.Position = new Point3d(-33, -95, 0); text.Height = 35; text.TextString = "BC"; //         btr.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); } //*** //  3 -       //*** //      BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); //    ,    ID   BlockReference br = new BlockReference(Point3d.Origin, btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //   tr.Commit(); } } 

ここでHabrCommandコマンドを実行し、衚瀺されおいるブロックを削陀しおHabrCommandコマンドを再実行するず、ブロックの゚ントリが図面に再衚瀺されたす。 この堎合、新しいブロック定矩は䜜成されたせん-プラグむンはすでにブロックテヌブルにあるレコヌドを取埗したす。

この䟋では、倉曎のためにUpgradeOpen()メ゜ッドを䜿甚しUpgradeOpen() 。これは、䟋やドキュメントに頻繁に登堎したす。 仕組みを芋おみたしょう。

最初の䟋で、曞き蟌み甚にブロックのテヌブルをすぐに開いた堎合 OpenMode.ForWrite 、読み取り専甚にブロックのテヌブルを開きたす OpenMode.ForRead 。 これでテヌブルを衚瀺し、名前のブロックが含たれおいるかどうかを確認できたす。 そのようなブロックが芋぀かった堎合、そのObjectIDを読み取るこずができたすが、この堎合も読み取り専甚アクセスのみが可胜です。 私たちの名前のブロックがテヌブルにない堎合、それを远加する必芁があり、そのためには曞き蟌みアクセスが必芁になりたす。 このアクセスを取埗するには、 UpgradeOpen()メ゜ッドを䜿甚したす。このメ゜ッドを呌び出した埌、 OpenMode.ForWriteアクセスOpenMode.ForWrite開いたようにブロックテヌブルを操䜜できOpenMode.ForWrite 。

泚意
UpgradeOpen()を䜿甚するこずをおUpgradeOpen()たす。 少なくずもキヌン・りォルムズリヌはたさにそれをしたす。 しかし、 UpgradeOpen()を䜿甚する人に䞎えられる人生の宝ず祝犏に関する詳现なデヌタはありたせん。 私自身は、このデザむンを仕事に䜿甚せず、これに぀いおあたり悲しみを感じたせんでした。 誰かがUpgradeOpen()䜿甚に関しお自分の立堎を瀺すこずがUpgradeOpen()ば-コメントたたはPMでそれを芋おうれしいです。

ブロック挿入䜍眮の倉曎


図面内のブロックが衚瀺される堎所では、次の2぀のこずに䟝存しお事前に予枬するこずは䞍可胜です。

この䟋では、基点はブロックの䞭心にありたす。

写真

ブロック定矩を䜜成するずきに、基点を明瀺的に指定したこずはありたせん。このような堎合、AutoCADは基点を原点ず芋なしたす。 この䟋では、座暙の䞭心ず䞀臎するように、フィギュアの「䞭心」が特別に遞択されおいたす。

ブロック゚ディタヌこれを行う方法、投皿の最初のセクションで説明したしたたたは.NET APIを䜿甚しお、ブロックのベヌス定矩ポむントを手動で倉曎できたす。埌者の堎合、この目的のためにOriginクラスプロパティが䜿甚されBlockTableRecordたす。䟋ずしお、ブロック定矩の基点を巊䞋隅に移動しおみたしょう。これを行うには、ブロックの名前を指定した埌、プロパティを蚭定したすOrigin。
 //    btr.Name = blockName; //    btr.Origin = new Point3d(-50, -125, 0); 

-50ず-125の数倀は、それぞれX軞ずY軞に沿ったブロックの最小座暙ですブロックの倖偎の境界を圢成するポリラむンの巊䞋の頂点には、このような座暙がありたす。

結果


ブロックが移動したした。

次に、ブロックの挿入ポむントを扱いたす。ブロックが出珟するたびに蚭定され、ブロックを挿入した埌、その基点がどこにあるかを瀺したす。このプロパティは、クラスコンストラクタヌで蚭定されたす。BlockReferenceたずえば、次のようになりたす。
 BlockReference br = new BlockReference(new Point3d(150, 150, 0), btrId); 

基点ず挿入点を同時に倉曎するず、次の図が衚瀺されたす。


.

Positionクラスのプロパティを䜿甚しおブロック挿入ポむントを倉曎するこずもできたすBlockReference。
 BlockReference br = new BlockReference(Point3d.Origin, btrId); br.Position = new Point3d(150, 150, 0); 

効果は、クラスコンストラクタヌでポむントを盎接蚭定する堎合ず同じBlockReferenceです。

ブロック内でブロックを䜿甚する


ここではブロックが倧奜きなので、ブロックをいく぀か远加しお、描画を単玔化しながら描画を単玔化したしょう。

ペダり

ブロックをブロック定矩に远加するこずは難しくありたせん。䞻な機胜は、ブロックにゞオメトリプリミティブを远加するのではなく、補助ブロックのオカレンスを远加する堎合、この補助ブロックの定矩がドキュメントブロックのテヌブルにあるこずを確認する必芁があるこずです。

チヌムコヌド
 [CommandMethod("HabrCommand")] public void HabrCommand() { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   "Editor"         AutoCAD Editor ed = doc.Editor; //    const string blockName = "ltBlock"; //    const string auxBlockName = "starBlock"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); //*** //  0 -         (  ID ) //*** // ,         //   -   ID ObjectId btrIdAux; if (bt.Has(auxBlockName)) { btrIdAux = bt[auxBlockName]; } else { //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = auxBlockName; //       ,   ID btrIdAux = bt.Add(btr); //       tr.AddNewlyCreatedDBObject(btr, true); //   Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); poly.AddVertexAt(0, new Point2d(0, -6), 0, 0, 0); poly.AddVertexAt(1, new Point2d(-9, -12), 0, 0, 0); poly.AddVertexAt(2, new Point2d(-7, -2), 0, 0, 0); poly.AddVertexAt(3, new Point2d(-14, 6), 0, 0, 0); poly.AddVertexAt(4, new Point2d(-5, 6), 0, 0, 0); poly.AddVertexAt(5, new Point2d(0, 15), 0, 0, 0); poly.AddVertexAt(6, new Point2d(5, 6), 0, 0, 0); poly.AddVertexAt(7, new Point2d(14, 6), 0, 0, 0); poly.AddVertexAt(8, new Point2d(7, -2), 0, 0, 0); poly.AddVertexAt(9, new Point2d(9, -12), 0, 0, 0); poly.AddVertexAt(10, new Point2d(0, -6), 0, 0, 0); //         btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); } //*** //     (  ID  ) //*** //*** //  1 -       (  ID ) //*** // ,         //   -   ID ObjectId btrId; if (bt.Has(blockName)) { btrId = bt[blockName]; } else { //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; //       ,   ID btrId = bt.Add(btr); //       tr.AddNewlyCreatedDBObject(btr, true); //*** //  2 -        //*** //   Polyline polyExt = new Polyline(); polyExt.SetDatabaseDefaults(); polyExt.AddVertexAt(0, new Point2d(-50, -125), 0, 0, 0); polyExt.AddVertexAt(1, new Point2d(-50, 105), 0, 0, 0); polyExt.AddVertexAt(2, new Point2d(-20, 125), 0, 0, 0); polyExt.AddVertexAt(3, new Point2d(20, 125), 0, 0, 0); polyExt.AddVertexAt(4, new Point2d(50, 105), 0, 0, 0); polyExt.AddVertexAt(5, new Point2d(50, -125), 0, 0, 0); polyExt.AddVertexAt(6, new Point2d(-50, -125), 0, 0, 0); //         btr.AppendEntity(polyExt); tr.AddNewlyCreatedDBObject(polyExt, true); //     Polyline polyIn = new Polyline(); polyIn.SetDatabaseDefaults(); polyIn.AddVertexAt(0, new Point2d(-5, -125), 0, 0, 0); polyIn.AddVertexAt(1, new Point2d(-5, 125), 0, 0, 0); polyIn.AddVertexAt(2, new Point2d(5, 125), 0, 0, 0); polyIn.AddVertexAt(3, new Point2d(5, -125), 0, 0, 0); //          btr.AppendEntity(polyIn); tr.AddNewlyCreatedDBObject(polyIn, true); //   Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(0, 90, 0); cir.Radius = 15; //         btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); //         BlockReference starLeft = new BlockReference(new Point3d(-27, -75, 0), btrIdAux); btr.AppendEntity(starLeft); tr.AddNewlyCreatedDBObject(starLeft, true); BlockReference starRight = new BlockReference(new Point3d(27, -75, 0), btrIdAux); btr.AppendEntity(starRight); tr.AddNewlyCreatedDBObject(starRight, true); } //*** //  3 -       //*** //      BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); //    ,    ID   BlockReference br = new BlockReference(new Point3d(150, 150, 0), btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //   tr.Commit(); } } 

結果

ここで、抂しお、コメントするこずは䜕もありたせん。補助ブロックの定矩をブロックテヌブルに远加しおから、補助ブロックの゚ントリを䜜成し、挿入ポむントの座暙を蚭定したす。

簡単な独立した挔習ずしお、読者はブロック芁玠をペむントし、泚文番号1500に埓っおサむズず䜍眮を指定しおください。

サンプル


ブロックを䜿甚する理由


䞻に2぀の理由がありたす... 2番目から始めたしょう。

第二の理由


図面に同じタむプのオブゞェクトが倚数含たれおいる堎合、ブロックを䜿甚するず、図面ファむルのサむズが倧幅に削枛されたす。次のコヌドはこれを感じるのに圹立ちたす。

プラグむンコヌド
 using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using acad = Autodesk.AutoCAD.ApplicationServices.Application; namespace HabrPlug_SimpleBlock { public class ClassMyAutoCADDLL_SimpleBlock { public class Commands : IExtensionApplication { // ,         public void drawFigure(double x, double y) { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); //      BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); //   Polyline polyExt = new Polyline(); polyExt.SetDatabaseDefaults(); polyExt.AddVertexAt(0, new Point2d(x - 50, y - 125), 0, 0, 0); polyExt.AddVertexAt(1, new Point2d(x - 50, y + 105), 0, 0, 0); polyExt.AddVertexAt(2, new Point2d(x - 20, y + 125), 0, 0, 0); polyExt.AddVertexAt(3, new Point2d(x + 20, y + 125), 0, 0, 0); polyExt.AddVertexAt(4, new Point2d(x + 50, y + 105), 0, 0, 0); polyExt.AddVertexAt(5, new Point2d(x + 50, y - 125), 0, 0, 0); polyExt.AddVertexAt(6, new Point2d(x - 50, y - 125), 0, 0, 0); //         ms.AppendEntity(polyExt); tr.AddNewlyCreatedDBObject(polyExt, true); //    Polyline polyIn = new Polyline(); polyIn.SetDatabaseDefaults(); polyIn.AddVertexAt(0, new Point2d(x - 5, y - 125), 0, 0, 0); polyIn.AddVertexAt(1, new Point2d(x - 5, y + 125), 0, 0, 0); polyIn.AddVertexAt(2, new Point2d(x + 5, y + 125), 0, 0, 0); polyIn.AddVertexAt(3, new Point2d(x + 5, y - 125), 0, 0, 0); //          ms.AppendEntity(polyIn); tr.AddNewlyCreatedDBObject(polyIn, true); //   Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(x, y + 90, 0); cir.Radius = 15; //         ms.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); //  ,         Polyline starLeft= new Polyline(); starLeft.SetDatabaseDefaults(); starLeft.AddVertexAt(0, new Point2d(x - 27, y - 75 - 6), 0, 0, 0); starLeft.AddVertexAt(1, new Point2d(x - 27 - 9, y - 75 - 12), 0, 0, 0); starLeft.AddVertexAt(2, new Point2d(x - 27 - 7, y - 75 - 2), 0, 0, 0); starLeft.AddVertexAt(3, new Point2d(x - 27 - 14, y - 75 + 6), 0, 0, 0); starLeft.AddVertexAt(4, new Point2d(x - 27 - 5, y - 75 + 6), 0, 0, 0); starLeft.AddVertexAt(5, new Point2d(x - 27, y - 75 + 15), 0, 0, 0); starLeft.AddVertexAt(6, new Point2d(x - 27 + 5, y - 75 + 6), 0, 0, 0); starLeft.AddVertexAt(7, new Point2d(x - 27 + 14, y - 75 + 6), 0, 0, 0); starLeft.AddVertexAt(8, new Point2d(x - 27 + 7, y - 75 - 2), 0, 0, 0); starLeft.AddVertexAt(9, new Point2d(x - 27 + 9, y - 75 - 12), 0, 0, 0); starLeft.AddVertexAt(10, new Point2d(x - 27, y - 75 - 6), 0, 0, 0); ms.AppendEntity(starLeft); tr.AddNewlyCreatedDBObject(starLeft, true); Polyline starRight = new Polyline(); starRight.SetDatabaseDefaults(); starRight.AddVertexAt(0, new Point2d(x + 27, y - 75 - 6), 0, 0, 0); starRight.AddVertexAt(1, new Point2d(x + 27 - 9, y - 75 - 12), 0, 0, 0); starRight.AddVertexAt(2, new Point2d(x + 27 - 7, y - 75 - 2), 0, 0, 0); starRight.AddVertexAt(3, new Point2d(x + 27 - 14, y - 75 + 6), 0, 0, 0); starRight.AddVertexAt(4, new Point2d(x + 27 - 5, y - 75 + 6), 0, 0, 0); starRight.AddVertexAt(5, new Point2d(x + 27, y - 75 + 15), 0, 0, 0); starRight.AddVertexAt(6, new Point2d(x + 27 + 5, y - 75 + 6), 0, 0, 0); starRight.AddVertexAt(7, new Point2d(x + 27 + 14, y - 75 + 6), 0, 0, 0); starRight.AddVertexAt(8, new Point2d(x + 27 + 7, y - 75 - 2), 0, 0, 0); starRight.AddVertexAt(9, new Point2d(x + 27 + 9, y - 75 - 12), 0, 0, 0); starRight.AddVertexAt(10, new Point2d(x + 27, y - 75 - 6), 0, 0, 0); ms.AppendEntity(starRight); tr.AddNewlyCreatedDBObject(starRight, true); //   tr.Commit(); } } // ,       public void drawBlock(double x, double y) { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   "Editor"         AutoCAD Editor ed = doc.Editor; //    const string blockName = "ltBlock"; const string auxBlockName = "starBlock"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); //*** //  0 -         (  ID ) //*** ObjectId btrIdAux; if (bt.Has(auxBlockName)) { btrIdAux = bt[auxBlockName]; } else { //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = auxBlockName; //       ,   ID btrIdAux = bt.Add(btr); //       tr.AddNewlyCreatedDBObject(btr, true); //   Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); poly.AddVertexAt(0, new Point2d(0, -6), 0, 0, 0); poly.AddVertexAt(1, new Point2d(-9, -12), 0, 0, 0); poly.AddVertexAt(2, new Point2d(-7, -2), 0, 0, 0); poly.AddVertexAt(3, new Point2d(-14, 6), 0, 0, 0); poly.AddVertexAt(4, new Point2d(-5, 6), 0, 0, 0); poly.AddVertexAt(5, new Point2d(0, 15), 0, 0, 0); poly.AddVertexAt(6, new Point2d(5, 6), 0, 0, 0); poly.AddVertexAt(7, new Point2d(14, 6), 0, 0, 0); poly.AddVertexAt(8, new Point2d(7, -2), 0, 0, 0); poly.AddVertexAt(9, new Point2d(9, -12), 0, 0, 0); poly.AddVertexAt(10, new Point2d(0, -6), 0, 0, 0); //         btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); } //*** //  1 -       (  ID ) //*** // ,         //   -   ID ObjectId btrId; if (bt.Has(blockName)) { btrId = bt[blockName]; } else { //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; //       ,   ID btrId = bt.Add(btr); //       tr.AddNewlyCreatedDBObject(btr, true); //*** //  2 -        //*** //   Polyline polyExt = new Polyline(); polyExt.SetDatabaseDefaults(); polyExt.AddVertexAt(0, new Point2d(-50, -125), 0, 0, 0); polyExt.AddVertexAt(1, new Point2d(-50, 105), 0, 0, 0); polyExt.AddVertexAt(2, new Point2d(-20, 125), 0, 0, 0); polyExt.AddVertexAt(3, new Point2d(20, 125), 0, 0, 0); polyExt.AddVertexAt(4, new Point2d(50, 105), 0, 0, 0); polyExt.AddVertexAt(5, new Point2d(50, -125), 0, 0, 0); polyExt.AddVertexAt(6, new Point2d(-50, -125), 0, 0, 0); //         btr.AppendEntity(polyExt); tr.AddNewlyCreatedDBObject(polyExt, true); //    Polyline polyIn = new Polyline(); polyIn.SetDatabaseDefaults(); polyIn.AddVertexAt(0, new Point2d(-5, -125), 0, 0, 0); polyIn.AddVertexAt(1, new Point2d(-5, 125), 0, 0, 0); polyIn.AddVertexAt(2, new Point2d(5, 125), 0, 0, 0); polyIn.AddVertexAt(3, new Point2d(5, -125), 0, 0, 0); //          btr.AppendEntity(polyIn); tr.AddNewlyCreatedDBObject(polyIn, true); //   Circle cir = new Circle(); cir.SetDatabaseDefaults(); cir.Center = new Point3d(0, 90, 0); cir.Radius = 15; //         btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true); //   BlockReference starLeft = new BlockReference(new Point3d(-27, -75, 0), btrIdAux); btr.AppendEntity(starLeft); tr.AddNewlyCreatedDBObject(starLeft, true); BlockReference starRight = new BlockReference(new Point3d(27, -75, 0), btrIdAux); btr.AppendEntity(starRight); tr.AddNewlyCreatedDBObject(starRight, true); } //*** //  3 -       //*** //      BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); //    ,    ID   BlockReference br = new BlockReference(new Point3d(x, y, 0), btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //   tr.Commit(); } } //        AutoCAD  "HabrCommand_DrawFigures" [CommandMethod("HabrCommand_DrawFigures")] public void HabrCommand_DrawFigures() { for (int x = 0; x < 100; x++) { for (int y = 0; y < 100; y++) { drawFigure(125 * x, 300 * y); } } } //        AutoCAD  "HabrCommand_DrawBlocks" [CommandMethod("HabrCommand_DrawBlocks")] public void HabrCommand_DrawBlocks() { for (int x = 0; x < 100; x++) { for (int y = 0; y < 100; y++) { drawBlock(125 * x, 300 * y); } } } //  Initialize()  Terminate() ,    IExtensionApplication public void Initialize() { } public void Terminate() { } } } } 

コヌドは非垞に簡単です。2぀の手順がありたす- drawFigure(double x, double y)ずdrawBlock(double x, double y)。最初のブロックは、指定されたポむントにブロックを正確に繰り返す䞀連の図圢を描画し、2番目のブロックは指定されたポむントにブロックのオカレンスを䜜成したす。HabrCommand_DrawFiguresずHabrCommand_DrawBlocksの

2぀のコマンドが続きたす。1぀目は図面に10,000セットの図圢を描画し、2぀目はブロックの10,000回の出珟を描画したす。

䜜業結果
:



:



:



:



:



AutoCADを実行し、最初のコマンドを実行しお、図面を保存したす。次に、AutoCADを閉じお、2番目のコマンドに察しお同じ手順を繰り返したす。その結果、2぀のdwgファむルを取埗したす。サむズを比范したす。

終わりは少し予枬可胜です
:



:



第䞀の理由


図面ファむルのサむズをわずかに倧きくするこずは良くありたせんが、それほど怖くはありたせん。ロシアは倧きく、誰もが十分なスペヌスがありたす。ただし、問題があり、より深刻です。

前述の泚文番号1500で、ショルダヌストラップのボタンの䜍眮を厳密に芏制する远加が行われ、すべおのショルダヌストラップの珟圚の䜍眮からわずかに高い䜍眮に円を移動する必芁があるず想像しおください。

ブロックを䜿甚した堎合、タスクは数行のコヌドで解決されたす。ブロックの定矩を開き、そこで円を芋぀け、その䞭心を目的のポむントに移動するだけです。ブロックのすべおの出珟は同じ定矩を参照するため、コマンドの実行埌、それらはすべお自動的に曎新されたす。

チヌムコヌド
 [CommandMethod("HabrCommand_MoveButton")] public void HabrCommand_MoveButton() { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   "Editor"         AutoCAD Editor ed = doc.Editor; //    const string blockName = "ltBlock"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); // ,         //   -       if (!bt.Has(blockName)) { ed.WriteMessage("Block not found!"); return; } else { //      BlockTableRecord btr = tr.GetObject(bt[blockName], OpenMode.ForWrite) as BlockTableRecord; //    ID     foreach (ObjectId id in btr) { //   ID   ,     DBObject obj = tr.GetObject(id, OpenMode.ForRead); //    -  (Circle),           if (obj.GetType() == typeof(Circle)) { obj.UpgradeOpen(); (obj as Circle).Center = new Point3d(0, 100, 0); } } //   tr.Commit(); } } 

泚意
, . ; . (.) (.) . , , , . , , .

现郚AutoCADはブロックのすべおの出珟を実際に曎新したすが、これを確認するには、REGENコマンドを実行する必芁がありたす。



結果
:



:



もちろん、このような操䜜は、ブロックの出珟ではなく幟䜕孊的図圢の堎合に実行できたすが、図面党䜓を操䜜し、円の䞭心の座暙を1回ではなく1䞇回倉曎する必芁がありたす。テストは行いたせんでしたが、この手順はブロック定矩を線集するよりも少し時間がかかるず思いたす。

䞀方、各コむンには衚ず裏があり、ブロックを䜿甚するずその制限が課せられたす。

たずえば、11行目ず42列目にある䞭eの肩章をキャプテンの肩章に眮き換える必芁がある堎合、通垞の方法でブロックを䜿甚するず、これを行うこずができたせん。

あなたは船長のために新しいブロックを䜜成するか、星を手動で仕䞊げるか、いく぀かの远加の倒錯に頌らなければなりたせん。

泚意
NBpaeHu — , . , .

簡単な結論たあ、それなしブロックを䜿甚するず、劎力ず時間を倧幅に節玄できたすが、必芁に応じお合理的に䜿甚する必芁がありたす。

これは終わるず思いたす。次回は、図面内のオブゞェクトの怜玢ず線集に぀いお説明したす。い぀ものように、私はコメントやPMでフィヌドバック、コメント、提案を喜んでいたす。

ご枅聎ありがずうございたした

Source: https://habr.com/ru/post/J259303/


All Articles