TheSwamp

Code Red => .NET => Topic started by: gablackburn on April 01, 2013, 05:35:40 PM

Title: Inserting a block to the BlockTableRecord ONLY - n00b question
Post by: gablackburn on April 01, 2013, 05:35:40 PM
Is it possible to insert a block to the BlockTableRecord without actually inserting the block into the drawing?

In my application, before there's any user interaction, I run some checks.  One of them is to add my blocks to the BlockTableRecord if they're not already there.  Everything I've seen online, wants the block position (3D coordinate) as part of the process of setting it up, and therefore the block is inserted at the same time it's added to the block table.

I've pared down my VB code just to keep it simple for the purposes of this example, of course I'll be doing error checking etc.

Code: [Select]
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.ApplicationServices
Imports System.IO

Public Class Class2
    <CommandMethod("AddtoBT")> _
    Public Sub InsertFromFileCommand()
        Dim FileNameLoc As String = "C:\TEMP\CIRCLESQUARE.DWG"
        Dim FileName As String = "CIRCLESQUARE"

        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor

        Using xDb As New Database(False, True)
            xDb.ReadDwgFile(FileNameLoc, FileShare.Read, True, Nothing)
            Using tr As Transaction = doc.TransactionManager.StartTransaction()
                Dim id As ObjectId = db.Insert(FileName, xDb, True)

                Dim btr As BlockTableRecord = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

                'I'D LIKE TO SKIP THIS STEP WHERE THE POINT3D IS REQUIRED
                Dim p3d As Point3d = New Point3d(0, 0, 0)
                Dim insert As New BlockReference(p3d, id)

                btr.AppendEntity(insert)
                insert.SetDatabaseDefaults()
                tr.AddNewlyCreatedDBObject(insert, True)
                tr.Commit()
            End Using
        End Using
    End Sub
End Class

Again, I'm still new to coding, so sorry for the n00b question.

George
Title: Re: Inserting a block to the BlockTableRecord ONLY - n00b question
Post by: BlackBox on April 01, 2013, 06:58:25 PM
I think you can pull what you need from Kean's post here (http://through-the-interface.typepad.com/through_the_interface/2010/01/creating-an-autocad-block-using-net.html)... Note that he first adds a new Block Definition, prior to inserting an instance (reference) of same.
Title: Re: Inserting a block to the BlockTableRecord ONLY - n00b question
Post by: Bryco on April 01, 2013, 08:22:55 PM
I think    Dim id As ObjectId = db.Insert(FileName, xDb, True) 
does all you want
Title: Re: Inserting a block to the BlockTableRecord ONLY - n00b question
Post by: gablackburn on April 02, 2013, 06:04:57 PM
Thanks Bryco and BlackBox, I went to Kean's blog and played around with his code, and I also tried what you suggested Bryco.  In the end, I have it working, but it seems like it's waaaaay too simple...  I feel like I'm doing something wrong here.

Code: [Select]
       
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.ApplicationServices
Imports System.IO
Public Class Class2
    <CommandMethod("AddtoBT")> _
       Public Sub InsBlock()
            Dim FileNameLoc As String = "C:\TEMP\CIRCLESQUARE.DWG"
            Dim FileName As String = "CIRCLESQUARE"
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim xDB As New Database(False, True)
            xDB.ReadDwgFile(FileNameLoc, FileShare.Read, True, Nothing)
            Using tr As Transaction = doc.TransactionManager.StartTransaction()
                Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForWrite), BlockTable)
                Dim id As ObjectId = db.Insert(FileName, xDB, True)
                tr.Commit()
            End Using
        End Sub

Of course I'll be running code to see if the block already exists in the BlockRecordTable, but this seems way too simple (as I've been fighting with this for a while now).
Title: Re: Inserting a block to the BlockTableRecord ONLY - n00b question
Post by: BlackBox on April 02, 2013, 06:59:30 PM
Just a couple of things that jump out:

Consider replacing this:
Code - vb.net: [Select]
  1. Dim FileName As String = "CIRCLESQUARE"

... With this:
Code - vb.net: [Select]
  1. Dim FileName As String = Path.GetFileNameWithoutExtension(FileNameLoc)

... More on System.IO.Path (http://msdn.microsoft.com/en-us/library/beth2052.aspx).



Given that you're only working with the Database, you might use a Database Transaction in lieu of a Document Transaction.
Title: Re: Inserting a block to the BlockTableRecord ONLY - n00b question
Post by: gablackburn on April 03, 2013, 11:04:01 AM
I didn't know that was in System.IO, that will save some time and lines of code, thanks Blackbox
Title: Re: Inserting a block to the BlockTableRecord ONLY - n00b question
Post by: mohnston on April 03, 2013, 12:16:19 PM
Just a couple of things that jump out:

Consider replacing this:
Code - vb.net: [Select]
  1. Dim FileName As String = "CIRCLESQUARE"

... With this:
Code - vb.net: [Select]
  1. Dim FileName As String = Path.GetFileNameWithoutExtension(FileNameLoc)

... More on System.IO.Path (http://msdn.microsoft.com/en-us/library/beth2052.aspx).



Given that you're only working with the Database, you might use a Database Transaction in lieu of a Document Transaction.

While we're on the subject it's good to be aware of these in the managed API:

SymbolUtilityServices.GetInsertPathNameFromBlockName
SymbolUtilityServices.GetBlockNameFromInsertPathName