Author Topic: Trying to insert block in current UCS  (Read 9090 times)

0 Members and 1 Guest are viewing this topic.

Patch61

  • Guest
Trying to insert block in current UCS
« on: March 25, 2011, 11:13:28 AM »
I'm trying to write a routine that will insert a block (with attributes) in the current UCS. I have cobbled this together from a few different sources, but I can't quite get the orientation to work consistently. I've tried a couple different examples of TransformBy on the block, but neither works consistently correctly.

Any ideas?

Also... How do I exit cleanly? When I'm done with my routine, it leaves the command line in a state that is not ready (no prompt). I have to hit Esc or Enter to get back the command prompt.


Code: [Select]
      Public Sub InsertDrawingAsBlock(ByVal doc As Document, ByVal path As String, ByVal blockname As String, _
                                      ByVal iPt As Point3d, Optional ByVal Space As String = "Model", _
                                      Optional ByVal LayerName As String = "Misc", Optional ByVal Xplode As Boolean = False, _
                                      Optional ByVal bRotate As Double = 0.0, Optional ByVal bXScale As Single = 1.0, _
                                      Optional ByVal bYScale As Single = 1.0, Optional ByVal bZScale As Single = 1.0)
         Dim curdb As Database = doc.Database
         Dim ed As Editor = doc.Editor
         Dim loc As DocumentLock = doc.LockDocument()
         Dim ucsMat As Matrix3d = ed.CurrentUserCoordinateSystem

         Using loc
            Dim blkid As ObjectId = ObjectId.Null
            Dim db As New Database(False, True)
            Using db
               db.ReadDwgFile(path, System.IO.FileShare.Read, True, "")
               blkid = curdb.Insert(path, db, True)
               Using tr As Transaction = doc.TransactionManager.StartTransaction()
                  Dim btr As BlockTableRecord = DirectCast(curdb.CurrentSpaceId.GetObject(OpenMode.ForWrite), BlockTableRecord)
                  Dim bt As BlockTable = DirectCast(tr.GetObject(curdb.BlockTableId, OpenMode.ForRead), BlockTable)
                  If bt.Has(blockname) Then
                     Dim btrId As ObjectId = bt(blockname).GetObject(OpenMode.ForRead).ObjectId
                     btr.UpgradeOpen()
                     Dim bref As New BlockReference(iPt, btrId)
                     btr.AppendEntity(bref)
                     tr.AddNewlyCreatedDBObject(bref, True)
                  Else
                  bt.UpgradeOpen()
                  Dim btrec As BlockTableRecord = DirectCast(blkid.GetObject(OpenMode.ForRead), BlockTableRecord)
                  btrec.UpgradeOpen()
                  btrec.Name = blockname
                  btrec.DowngradeOpen()
                     Using btr
                        'iPt = iPt.TransformBy(ucsMat)
                        Using bref As New BlockReference(iPt, blkid)
                           Dim mat As Matrix3d = Matrix3d.Identity
                           bref.TransformBy(mat)
                           'bref.TransformBy(ucsMat)
                           'Rotate  
                           bref.Rotation = bRotate * (Math.PI / 180)
                           'Scale factor
                           bref.ScaleFactors = New Scale3d(bXScale, bYScale, bZScale)
                           btr.AppendEntity(bref)
                           tr.AddNewlyCreatedDBObject(bref, True)

                           Using btAttRec As BlockTableRecord = DirectCast(bref.BlockTableRecord.GetObject(OpenMode.ForRead), BlockTableRecord)
                              Dim atcoll As Autodesk.AutoCAD.DatabaseServices.AttributeCollection = bref.AttributeCollection
                              For Each subid As ObjectId In btAttRec
                                 Dim ent As Entity = DirectCast(subid.GetObject(OpenMode.ForRead), Entity)
                                 Dim attDef As AttributeDefinition = TryCast(ent, AttributeDefinition)
                                 If attDef IsNot Nothing Then
                                    'ed.WriteMessage(vbLf & "Value: " + attDef.TextString)
                                    Dim attRef As New AttributeReference()
                                    attRef.SetPropertiesFrom(attDef)
                                    attRef.Visible = attDef.Visible
                                    attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)
                                    attRef.HorizontalMode = attDef.HorizontalMode
                                    attRef.VerticalMode = attDef.VerticalMode
                                    attRef.Rotation = attDef.Rotation
                                    attRef.TextStyleId = attDef.TextStyleId
                                    attRef.Position = attDef.Position + iPt.GetAsVector()
                                    attRef.Tag = attDef.Tag
                                    attRef.FieldLength = attDef.FieldLength
                                    attRef.TextString = attDef.TextString
                                    attRef.AdjustAlignment(curdb)
                                    atcoll.AppendAttribute(attRef)
                                    tr.AddNewlyCreatedDBObject(attRef, True)
                                 End If
                              Next
                           End Using
                           bref.DowngradeOpen()

                           'Does it need to be exploded?
                           If Xplode = True Then
                              bref.ExplodeToOwnerSpace()
                              bref.Erase()
                           End If

                        End Using
                     End Using
                     btrec.DowngradeOpen()
                     bt.DowngradeOpen()
                     ed.Regen()

                  End If
                  tr.Commit()
               End Using
            End Using
         End Using
      End Sub
« Last Edit: March 25, 2011, 11:20:47 AM by Patch61 »

fixo

  • Guest
Re: Trying to insert block in current UCS
« Reply #1 on: March 25, 2011, 12:04:33 PM »
Try use wcs insertion point, something like


Code: [Select]
       Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim pt As Point3d = New Point3d(100, 100, 100)
            Dim ed As Editor = doc.Editor
            Dim mat As Matrix3d = ed.CurrentUserCoordinateSystem
            Dim ucs As CoordinateSystem3d = mat.CoordinateSystem3d
            Dim wcsmat As Matrix3d = _
                  Matrix3d.AlignCoordinateSystem(ucs.Origin, ucs.Xaxis, ucs.Yaxis, ucs.Zaxis, _
                                          Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis)
            Dim inspt As Point3d = pt.TransformBy(wcsmat)
            InsertDrawingAsBlock(doc, "C:\Test\blah.dwg", "newblock", inspt, , , , , , , )

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #2 on: March 25, 2011, 01:13:09 PM »
Thanks for the reply and the help. I appreciate the effort!

However, from what I can tell, all that you are transforming into the UCS is the insertion point, not the inserted block. I'm trying to adapt what you posted into my program to transform the block reference, but I'm not having much luck.

It is still baffling to me that AutoDesk has done all this effort with their .Net API, but have totally missed the boat on useable documentation. So extremely far from a professional job that one is inclined to believe they are using the 'many monkees pounding keys for many days' method of documentation. Or perhaps, the person in charge of documentation is just plain stupid. Either scenario seems about as likely after trying to use the crap they shat on us.


Steve
« Last Edit: March 25, 2011, 01:19:48 PM by Patch61 »

kaefer

  • Swamp Rat
  • Posts: 572
Re: Trying to insert block in current UCS
« Reply #3 on: March 25, 2011, 04:13:56 PM »
However, from what I can tell, all that you are transforming into the UCS is the insertion point, not the inserted block. I'm trying to adapt what you posted into my program to transform the block reference, but I'm not having much luck.

Why would that be? You're already utilizing the TransformBy() method, just pass it an adaquate Matrix3d. Besides, the concept of combining transformations by multiplication of their matrices shouldn't be alien too.

Your other issue may be solved missing-prompt-wise by Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt().

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Trying to insert block in current UCS
« Reply #4 on: March 25, 2011, 07:54:15 PM »
Patch 61,
What does this represent
ByVal iPt As Point3d

??

Is the variable holding a point in the current UCS or in WORLD (note that the current UCS may BE World).

Points selected by getpoint will be in the current UCS.



Quote
However, from what I can tell, all that you are transforming into the UCS is the insertion point, not the inserted block.

Your understanding is incorrect.
Fixo's code transforms the UCS defined pt to the WCS defined insPt
Then inserts the block at  insPt.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Trying to insert block in current UCS
« Reply #5 on: March 25, 2011, 08:18:14 PM »

addendum

Does this
Quote
Trying to insert block in current UCS.

actually mean you want to do this :

Insert a Block at a point defined in the current UCS ??
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

kaefer

  • Swamp Rat
  • Posts: 572
Re: Trying to insert block in current UCS
« Reply #6 on: March 26, 2011, 03:55:28 AM »
Does this
Quote
Trying to insert block in current UCS.

actually mean you want to do this :

Insert a Block at a point defined in the current UCS ??

I think he means:

Insert a block at a point defined in the current UCS and align it with the XY plane of the current UCS.

Discounting rotation and scaling, the transform could look like
Code: [Select]
    db.GetUcsMatrix * Matrix3d.Displacement(iPt - Point3d.Origin)

The database extension was discussed recently http://www.theswamp.org/index.php?topic=37409.msg425283#msg425283,
selected earlier mentions are http://www.theswamp.org/index.php?topic=19035.msg231983#msg231983, http://www.theswamp.org/index.php?topic=20656.msg251052#msg251052 and way back in 2005 http://www.theswamp.org/index.php?topic=7657.msg97523#msg97523.

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #7 on: March 28, 2011, 08:57:53 AM »
Does this
Quote
Trying to insert block in current UCS.

actually mean you want to do this :

Insert a Block at a point defined in the current UCS ??

I think he means:

Insert a block at a point defined in the current UCS and align it with the XY plane of the current UCS.

Discounting rotation and scaling, the transform could look like
Code: [Select]
   db.GetUcsMatrix * Matrix3d.Displacement(iPt - Point3d.Origin)

The database extension was discussed recently http://www.theswamp.org/index.php?topic=37409.msg425283#msg425283,
selected earlier mentions are http://www.theswamp.org/index.php?topic=19035.msg231983#msg231983, http://www.theswamp.org/index.php?topic=20656.msg251052#msg251052 and way back in 2005 http://www.theswamp.org/index.php?topic=7657.msg97523#msg97523.

Yes, I want to take a user-clicked location and insert a block at that location, with the block being aligned to the current UCS, just like how the Insert command works in AutoCAD.

You guys have given me something new to try, so I will integrate your ideas with my code and see what we end up with. I've never completely understood matrix math... it hurts my brain!

Thanks for the help!


Steve
« Last Edit: March 28, 2011, 09:12:53 AM by Patch61 »

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #8 on: March 28, 2011, 09:51:23 AM »
How would I use this in the context of my posted code? Is this returning a Matrix3D object?

Code: [Select]
   db.GetUcsMatrix * Matrix3d.Displacement(iPt - Point3d.Origin)

Again, matrix math is greek to me. And the poor documentation from AutoDesk leaves me scratching my head on these issues.  :|

Update:
When I try to use this as follows:
Code: [Select]
Dim UserMat As Matrix3d
UserMat = db.GetUcsMatrix * Matrix3d.Displacement(iPt - Point3d.Origin)

Visual Studio tells me that 'GetUcsMatrix' is not a member of 'AutoDesk.AutoCAD.DatabaseServices.Database'.

When I try to add the extension to my project, VS tells me 'Extension methods can be defined only in modules.' Huh? What modules? I'm working in VB, if that matters.

Ugh. I feel like a caveman trying to understand this. Inserting a block should be a simple thing. I hate this .Net API.  :realmad:


Thanks,
Steve
« Last Edit: March 28, 2011, 10:27:12 AM by Patch61 »

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #9 on: March 29, 2011, 08:36:30 AM »
Help! Please? Anybody? :cry:

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Trying to insert block in current UCS
« Reply #10 on: March 29, 2011, 08:48:44 AM »

I'll have a play tomorrow for you
.. but I do think you may have a little reading to do :)
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #11 on: March 29, 2011, 09:03:33 AM »

I'll have a play tomorrow for you
.. but I do think you may have a little reading to do :)

Thanks, Kerry!

I don't mind reading and learning at all. Just, in this case, I have no clue what to read!

Steve

gile

  • Water Moccasin
  • Posts: 2261
  • Marseille, France
Re: Trying to insert block in current UCS
« Reply #12 on: March 29, 2011, 11:29:24 AM »
Hi,

Here's a little sample to insert a bloc in the current UCS.

EDIT there was something wrong in the precedent code.
This one is a little bit more explicit

Code: [Select]
        [CommandMethod("TEST")]
        public void InsertInCurrentUcs()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptResult pr = ed.GetString("\nEnter the block name: ");
            if (pr.Status != PromptStatus.OK)
                return;
            string bName = pr.StringResult;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (!bt.Has(bName))
                {
                    ed.WriteMessage("\nCan't find '{0}' block.", bName);
                    return;
                }

                PromptPointResult ppr = ed.GetPoint("\nSpecify insertion point: ");
                if (ppr.Status != PromptStatus.OK)
                    return;

                // Get the current UCS Z axis (extrusion direction)
                Matrix3d ucsMat = ed.CurrentUserCoordinateSystem;
                CoordinateSystem3d ucs = ucsMat.CoordinateSystem3d;
                Vector3d zdir = ucsMat.CoordinateSystem3d.Zaxis;

                // Get the OCS corresponding to UCS Z axis
                Matrix3d ocsMat = MakeOcs(zdir);

                // Transform the input point from UCS to OCS
                Point3d pt = ppr.Value.TransformBy(ucsMat.PreMultiplyBy(ocsMat));

                // Get the X axis of the OCS
                Vector3d ocsXdir = ocsMat.CoordinateSystem3d.Xaxis;

                // Get the UCS rotation (angle between the OCS X axis and the UCS X axis)
                double rot = ocsXdir.GetAngleTo(ucs.Xaxis, zdir);

                BlockTableRecord btr =
                    (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                BlockReference br = new BlockReference(pt, bt[bName]);
                br.Position = pt;
                br.Rotation = rot;
                br.Normal = zdir;
                btr.AppendEntity(br);
                tr.AddNewlyCreatedDBObject(br, true);
                tr.Commit();
            }
        }

        // Return an OCS Matrix3d using the 'Arbitrary Axis Algoriythm'
        private Matrix3d MakeOcs(Vector3d zdir)
        {
            double d = 1.0 / 64.0;
            zdir = zdir.GetNormal();
            Vector3d xdir = Math.Abs(zdir.X) < d && Math.Abs(zdir.Y) < d ?
                Vector3d.YAxis.CrossProduct(zdir).GetNormal() :
                Vector3d.ZAxis.CrossProduct(zdir).GetNormal();
            Vector3d ydir = zdir.CrossProduct(xdir).GetNormal();
            return new Matrix3d(new double[16]{
                xdir.X, xdir.Y, xdir.Z, 0.0,
                ydir.X, ydir.Y, ydir.Z, 0.0,
                zdir.X, zdir.Y, zdir.Z, 0.0,
                0.0, 0.0, 0.0, 1.0});
        }
« Last Edit: March 29, 2011, 12:37:05 PM by gile »
Speaking English as a French Frog

kaefer

  • Swamp Rat
  • Posts: 572
Re: Trying to insert block in current UCS
« Reply #13 on: March 29, 2011, 12:11:53 PM »
Here's a little sample to insert a bloc in the current UCS.

Okay, I'll bite. What do you win by transforming the insertion point only and do the calculation of the normal direction manually? I concede that it's always useful to have the know how to do it. Besides, there's little trick in your code: Setting the Position property isn't the same thing as calling the constructor with the insertion point.

Let's compare:
Code: [Select]
type acApp = Autodesk.AutoCAD.ApplicationServices.Application

type Database with
    member db.IsPaperSpace =
        if db.TileMode then false
        else
            let ed = acApp.DocumentManager.MdiActiveDocument.Editor
            (db.PaperSpaceVportId = ed.CurrentViewportObjectId)

    member db.GetUcsMatrix =
        let (origin, xAxis, yAxis) =
            if db.IsPaperSpace then
                db.Pucsorg, db.Pucsxdir, db.Pucsydir
            else
                db.Ucsorg, db.Ucsxdir, db.Ucsydir
        Matrix3d.AlignCoordinateSystem(
            Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
            origin, xAxis, yAxis, xAxis.CrossProduct yAxis )

let myInsertUCS (tr: Transaction) _ (db: Database) (btrOid: ObjectId) (iPt: Point3d) =
        let mat =
            db.GetUcsMatrix *
            Matrix3d.Displacement(iPt- Point3d.Origin)
        let btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) :?> BlockTableRecord
        let bref = new BlockReference(Point3d.Origin, btrOid)
        bref.TransformBy mat
        btr.AppendEntity bref |> ignore
        tr.AddNewlyCreatedDBObject(bref, true)

let gileInsertUCS (tr: Transaction) (ed: Editor) (db: Database) (btrOid: ObjectId) (iPt: Point3d) =
    // Transform the input point from UCS to WCS
    let ucsMat = ed.CurrentUserCoordinateSystem
    let pt = iPt.TransformBy ucsMat

    // Get the current UCS Z axis (extrusion direction)
    let ucs = ucsMat.CoordinateSystem3d
    let zdir = ucs.Zaxis

    // Get the X axis of the OCS from the current UCS Z axis
    // (using the 'Arbitrary Axis Algoriythm')
    let d = 1.0 / 64.0
    let ocsXdir =
        if abs zdir.X < d && abs zdir.Y < d then
            Vector3d.YAxis.CrossProduct zdir
        else
            Vector3d.ZAxis.CrossProduct zdir

    // Get the UCS rotation (angle between the OCS X axis and the UCS X axis)
    let rot = ocsXdir.GetAngleTo(ucs.Xaxis, zdir);

    let btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) :?> BlockTableRecord
    let bref =
        new BlockReference(
            Point3d.Origin, btrOid,
            Rotation = rot,
            Normal = zdir,
            Position = pt )
    btr.AppendEntity bref |> ignore
    tr.AddNewlyCreatedDBObject(bref, true)

let insertUCSCmd f =
    let doc = acApp.DocumentManager.MdiActiveDocument
    let db = doc.Database
    let ed = doc.Editor
    let pstr =
        new PromptStringOptions(
            "Block name",
            AllowSpaces = true )
        |> ed.GetString
    if pstr.Status = PromptStatus.OK then
        use tr = db.TransactionManager.StartTransaction()
        let bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) :?> BlockTable
        if not(bt.Has pstr.StringResult) then
            ed.WriteMessage("\n{0} not defined. ", pstr.StringResult)
        else
            let ppr = ed.GetPoint("Insertion point")
            if ppr.Status = PromptStatus.OK then
                f tr ed db bt.[pstr.StringResult] ppr.Value
        tr.Commit()

[<CommandMethod "myInsertUCS">]
let myInserUCSCmd() = insertUCSCmd myInsertUCS

[<CommandMethod "gileInsertUCS">]
let gileInserUCSCmd() = insertUCSCmd gileInsertUCS

gile

  • Water Moccasin
  • Posts: 2261
  • Marseille, France
Re: Trying to insert block in current UCS
« Reply #14 on: March 29, 2011, 12:58:28 PM »
You're right kaefer, I loose myself in the OCS route...
Speaking English as a French Frog

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #15 on: March 29, 2011, 01:16:25 PM »
Thanks for the help, guys!

Kaefer,

What language is that? It's almost basic, but Visual Studio doesn't like it.  :wink:

gile

  • Water Moccasin
  • Posts: 2261
  • Marseille, France
Re: Trying to insert block in current UCS
« Reply #16 on: March 29, 2011, 01:36:37 PM »
Quote
What language is that? It's almost basic, but Visual Studio doesn't like it.
It's F# and Visual Studio DO like it, it's part of Visual Studio 2010 and can be added to Visual Studio 2008 (not Express versions). See here.

kaefer,
It seems that your 'db.GetUcsMatrix' function returns the same as the native ed.CurrentUserCoordinateSystem().

Here's a C# code using the 'righter way'.

Code: [Select]
        [CommandMethod("TEST")]
        public void InsertInCurrentUcs()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptResult pr = ed.GetString("\nEnter the block name: ");
            if (pr.Status != PromptStatus.OK)
                return;
            string bName = pr.StringResult;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (!bt.Has(bName))
                {
                    ed.WriteMessage("\nCan't find '{0}' block.", bName);
                    return;
                }
                PromptPointResult ppr = ed.GetPoint("\nSpecify insertion point: ");
                if (ppr.Status != PromptStatus.OK)
                    return;
                Matrix3d ucsMat = ed.CurrentUserCoordinateSystem;
                BlockTableRecord btr =
                    (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                BlockReference br = new BlockReference(Point3d.Origin, bt[bName]);
                br.TransformBy(ucsMat * Matrix3d.Displacement(ppr.Value - Point3d.Origin));
                btr.AppendEntity(br);
                tr.AddNewlyCreatedDBObject(br, true);
                tr.Commit();
            }
        }
« Last Edit: March 29, 2011, 01:51:22 PM by gile »
Speaking English as a French Frog

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #17 on: March 29, 2011, 01:39:54 PM »
See here.

I assume that was supposed to be a link, but it's just bold. I have Visual Studio 2008 Standard.


gile

  • Water Moccasin
  • Posts: 2261
  • Marseille, France
Re: Trying to insert block in current UCS
« Reply #18 on: March 29, 2011, 01:54:50 PM »
Oopss !!!....
I add the link to the message, you can download F# 2.0 it will be added to VS standard.
Speaking English as a French Frog

kaefer

  • Swamp Rat
  • Posts: 572
Re: Trying to insert block in current UCS
« Reply #19 on: March 29, 2011, 02:39:58 PM »
kaefer,
It seems that your 'db.GetUcsMatrix' function returns the same as the native ed.CurrentUserCoordinateSystem().

Hi, gile.

Yeah, looks like it does. Wouldn't have thought that. Package label said:
Quote
Returns the current user coordinate system points.

Time to display a sheepish grin and stow away the much touted Database extension until there's no Editor to get a property of.

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #20 on: March 29, 2011, 02:47:19 PM »
Thanks for the help, guys. I'll try the new code out as soon as I get a chance.


Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #21 on: March 30, 2011, 10:21:51 AM »
Gile,

I'm not having much luck integrating what you posted into the routine I posted. Some things just don't seem kosher. Like the Point3D.Origin you are using. Where is that from? I have the insertion point defined as iPt (using GetPoint), so I figured you meant to use that. But it won't let me use iPt.Origin, so I don't get what is going on. I guess if I knew enough to make your code work in my routine, I probably wouldn't have needed to ask for help in the first place.

Is there any chance you could slip your code into my routine? I need to insert a block from a file (checking to see if it already exists in the drawing) at the user-selected point, aligned with the current UCS. It also has to handle attributes.

I'm sure eventually this all will make sense, but right now, it doesn't. I feel like I am shooting in the dark here and I'm not hitting the target.


Thanks,
Steve
« Last Edit: March 30, 2011, 10:31:53 AM by Patch61 »

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #22 on: March 30, 2011, 10:44:53 AM »
Point3d.Origin is a read-only Shared(static for you C#) property of the Point3d

gile's code

Code: [Select]
                    Dim ucsMatrix As Matrix3d = ed.CurrentUserCoordinateSystem
                    Dim bref As New BlockReference(Point3d.Origin)
                    bref.TransformBy(ucsMatrix * Matrix3d.Displacement(iPt - Point3d.Origin))

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #23 on: March 30, 2011, 10:51:06 AM »
This is it from reflector

Code: [Select]
Public Shared ReadOnly Property Origin As Point3d
    Get
        Return New Point3d(0, 0, 0)
    End Get
End Property
 

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #24 on: March 30, 2011, 10:51:55 AM »
Point3d.Origin is a read-only Shared(static for you C#) property of the Point3d

gile's code

Code: [Select]
                    Dim ucsMatrix As Matrix3d = ed.CurrentUserCoordinateSystem
                    Dim bref As New BlockReference(Point3d.Origin)
                    bref.TransformBy(ucsMatrix * Matrix3d.Displacement(iPt - Point3d.Origin))

I understand what it is, I don't understand his use of a property of something that has not been assigned a value. That is why I asked where it is from. And, like I mentioned, I don't understand why it wouldn't let me use iPt.Origin in its place. I'm beginning to think I'm missing some basic thing here and that is causing me confusion.


gile

  • Water Moccasin
  • Posts: 2261
  • Marseille, France
Re: Trying to insert block in current UCS
« Reply #25 on: March 30, 2011, 12:25:55 PM »
Origin is a static (Shared) property of the Point3d class, that means it cannot be used with instances of this class.
Point3d.Origin is a kind of constant equivalent to : new Point3d(0.0, 0.0, 0.0).

In the code I posted (inspired by kaefer's one) the block reference is first inserted in 0, 0, 0 and then tranformed by a matix which is a combination of the UCS matrix and a displacement (vector) from 0, 0, 0 ti iPt so that the block refrence is rotate and displaced about the UCS and then displaced from the UCS origin to the specified insertion point.
Speaking English as a French Frog

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #26 on: March 30, 2011, 12:43:44 PM »
Vb will let you use a shared a member with a instance of a the class it just generates a warning.
This will complie ans run but with warnings
Code: [Select]
                    Dim pointOrgin As New Point3d(0.0, 0.0, 0.0)
                    Dim pnt As Point3d = pointOrgin.Origin

                    Dim pointy As Point3d

                    Dim ucsMatrix As Matrix3d = ed.CurrentUserCoordinateSystem

                    Dim bref As New BlockReference(pointy.Origin, bt("BlockName"))

                    bref.TransformBy(ucsMatrix * Matrix3d.Displacement(pnt - pnt.Origin))

Each instance of the class does not get it own copy of a shared member. It is "class wide" or each instance "shares" hence Shared.
The property has been assinged and is assigned at the class level as read-only.
A good reason or example for using a shared property is to a count how many instances of a class have been created.

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #27 on: March 30, 2011, 01:31:26 PM »
I think MS thinking is accessing a static property through the Class name instead of a instance makes your code harder to read, but in way a way is seems natural to be able to access it through a instance since it is meant to be "shared".

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #28 on: March 30, 2011, 03:52:37 PM »
OK, no matter what I do, this is failing. It fails if the block exists, and it fails for a different reason if the block is loaded from disk. I don't know what I am doing wrong.

Code: [Select]
      Public Sub InsertDrawingAsBlock(ByVal doc As Document, ByVal path As String, ByVal blockname As String, _
                                      ByVal iPt As Point3d, Optional ByVal Space As String = "Model", _
                                      Optional ByVal LayerName As String = "Misc", Optional ByVal Xplode As Boolean = False, _
                                      Optional ByVal bRotate As Double = 0.0, Optional ByVal bXScale As Single = 1.0, _
                                      Optional ByVal bYScale As Single = 1.0, Optional ByVal bZScale As Single = 1.0)
         Dim curdb As Database = doc.Database
         Dim ed As Editor = doc.Editor
         Dim loc As DocumentLock = doc.LockDocument()
         Using loc
            Dim blkid As ObjectId = ObjectId.Null
            Dim db As Database = doc.Database
            Using db
               db.ReadDwgFile(path, System.IO.FileShare.Read, True, "")
               blkid = curdb.Insert(path, db, True)
               Using tr As Transaction = db.TransactionManager.StartTransaction()
                  Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                  Dim ucsMat As Matrix3d = ed.CurrentUserCoordinateSystem
                  Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                  If bt.Has(blockname) Then
                     Dim br As New BlockReference(Point3d.Origin, bt(blockname))
                     br.TransformBy(ucsMat * Matrix3d.Displacement(iPt - Point3d.Origin))
                     Dim btrId As ObjectId = bt(blockname).GetObject(OpenMode.ForRead).ObjectId
                     btr.UpgradeOpen()
                     btr.AppendEntity(br)
                     tr.AddNewlyCreatedDBObject(br, True)
                  Else
                     bt.UpgradeOpen()
                     'Dim br As New BlockReference(Point3d.Origin, bt(blockname))
                     'br.TransformBy(ucsMat * Matrix3d.Displacement(iPt - Point3d.Origin))
                     Dim btrec As BlockTableRecord = DirectCast(blkid.GetObject(OpenMode.ForRead), BlockTableRecord)
                     btrec.UpgradeOpen()
                     btrec.Name = blockname
                     btrec.DowngradeOpen()

                     Using btr
                        Using bref As New BlockReference(iPt, blkid)
                           'Rotate 45 degrees
                           '45 * (Math.PI/180)
                           bref.Rotation = bRotate * (Math.PI / 180)
                           'Scale factor
                           bref.ScaleFactors = New Scale3d(bXScale, bYScale, bZScale)
                           bref.TransformBy(ucsMat * Matrix3d.Displacement(iPt - Point3d.Origin))
                           btr.AppendEntity(bref)

                           tr.AddNewlyCreatedDBObject(bref, True)

                           Using btAttRec As BlockTableRecord = DirectCast(bref.BlockTableRecord.GetObject(OpenMode.ForRead), BlockTableRecord)
                              Dim atcoll As Autodesk.AutoCAD.DatabaseServices.AttributeCollection = bref.AttributeCollection
                              For Each subid As ObjectId In btAttRec
                                 Dim ent As Entity = DirectCast(subid.GetObject(OpenMode.ForRead), Entity)
                                 Dim attDef As AttributeDefinition = TryCast(ent, AttributeDefinition)
                                 If attDef IsNot Nothing Then
                                    Dim attRef As New AttributeReference()
                                    attRef.SetPropertiesFrom(attDef)
                                    attRef.Visible = attDef.Visible
                                    attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)
                                    attRef.HorizontalMode = attDef.HorizontalMode
                                    attRef.VerticalMode = attDef.VerticalMode
                                    attRef.Rotation = attDef.Rotation
                                    attRef.TextStyleId = attDef.TextStyleId
                                    attRef.Position = attDef.Position + iPt.GetAsVector()
                                    attRef.Tag = attDef.Tag
                                    attRef.FieldLength = attDef.FieldLength
                                    attRef.TextString = attDef.TextString
                                    attRef.AdjustAlignment(curdb)
                                    atcoll.AppendAttribute(attRef)
                                    tr.AddNewlyCreatedDBObject(attRef, True)
                                 End If
                              Next
                           End Using
                           bref.DowngradeOpen()

                           'Does it need to be exploded?
                           If Xplode = True Then
                              bref.ExplodeToOwnerSpace()
                              bref.Erase()
                           End If

                        End Using
                     End Using
                     btrec.DowngradeOpen()
                     bt.DowngradeOpen()
                     ed.Regen()

                  End If
                  tr.Commit()
               End Using
            End Using
         End Using
      End Sub

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #29 on: March 30, 2011, 04:04:44 PM »
Dim curdb As Database = doc.Database

  Dim db As Database = doc.Database
            Using db
               db.ReadDwgFile(path, System.IO.FileShare.Read, True, "")


Just looking real quick you are using the same database from whatever doc is passed in as a parameter
You need to create a new database before you call ReadDwgFile

gile

  • Water Moccasin
  • Posts: 2261
  • Marseille, France
Re: Trying to insert block in current UCS
« Reply #30 on: March 30, 2011, 04:11:43 PM »
Don't make VB more verbose than it is:
Dim btrId As ObjectId = bt(blockname).GetObject(OpenMode.ForRead).ObjectId
is the same as:
Dim btrId As ObjectId = bt(blockname)
anyway, you can throw this expression as you never use btrId...

IMO, rather than trying to integrate the code I posted to yours, translate it to VB, try it, then add the features you want one by one, trying and debuging the code at each step.
Speaking English as a French Frog

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #31 on: March 30, 2011, 04:14:28 PM »
By the name of your method I would assume you want insert another drawing as a block?

blkid = curdb.Insert(path, db, True)


Would you like to start fresh with option strict off so you do not need all the directcast?


Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Trying to insert block in current UCS
« Reply #32 on: March 30, 2011, 04:19:11 PM »

Also ..
It may help if you included the sub/function that you are calling this from
... would make it so much easier to debug explicitly for your situation.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #33 on: March 30, 2011, 04:19:39 PM »
Option strict *is* off... Directcast is something I know NOTHING about, anyway. I got that from somebody's example or a conversion from C#.

I am hating .Net more and more. I used to love programming. Since .Net it has been headache after headache.

Here is the sub I am calling from (a button click - the BIC is a class that includes my block handling routines):

Code: [Select]
  Private Sub cmdInsert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdInsert.Click
      'Dim InsStatus As Integer
      Me.Hide()
      Dim pPtRes As PromptPointResult
      Dim pPtOpts As PromptPointOptions = New PromptPointOptions("")
      Dim DWGname As String
      Dim InsSpace As String = "Model"
      Dim eXplode As Boolean = False
      Dim InsLayer As String = "Misc"
      Dim strTemp As String
      Dim acDoc As Document = AcApp.DocumentManager.MdiActiveDocument

      CurDWG = TreeView1.SelectedNode.Tag
      DWGname = IO.Path.GetFileNameWithoutExtension(CurDWG)

      If My.Computer.Keyboard.ShiftKeyDown Then
         OpenFile(CurDWG, False)
      Else

         If VBStr.Right(DWGname, 3) = "-ps" Then
            'DWGname = VBStr.Left(DWGname, Len(DWGname) - 3)
            InsSpace = "Paper"
            InsLayer = "Misc"
         Else
            ' Determine Layer, Space, and eXplode
            strTemp = VBStr.Left(VBStr.Right(DWGname, 6), 5)
            If VBStr.Right(DWGname, 1) = "L" And IsNumeric(strTemp) Then
               eXplode = True
            End If
            InsSpace = "Model"
            InsLayer = "Misc"
            strTemp = VBStr.Left(VBStr.Right(DWGname, 6), 5)
         End If
         ChangeSpace(InsSpace)
         'Insert the drawing as a block
         '' Prompt for the start point
         pPtOpts.Message = vbLf & "Click where you wish to insert the block reference: "
         pPtRes = CurDoc.Editor.GetPoint(pPtOpts)
         Dim ptIns As Point3d = pPtRes.Value
         '' Exit if the user presses ESC or cancels the command
         If pPtRes.Status = PromptStatus.Cancel Then Exit Sub
         LYR.SetLayerCurrent(InsLayer)
         BIC.InsertDrawingAsBlock(CurDoc, CurDWG, DWGname, ptIns, InsSpace, InsLayer, eXplode)
      End If

      Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt()
   End Sub

« Last Edit: March 30, 2011, 04:23:59 PM by Patch61 »

gile

  • Water Moccasin
  • Posts: 2261
  • Marseille, France
Re: Trying to insert block in current UCS
« Reply #34 on: March 30, 2011, 04:25:55 PM »
Quote
I am hating .Net more and more. I used to love programming.
Take the LISP route...
Speaking English as a French Frog

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #35 on: March 30, 2011, 04:27:34 PM »
Quote
I am hating .Net more and more. I used to love programming.
Take the LISP route...

Been there, done that. Have a U.S. Patent for artificially intelligent engineering software I wrote in Lisp.
I WILL NOT GO BACK!!!!

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #36 on: March 30, 2011, 04:28:39 PM »
I do not see CurDoc declared, but who cares.

Would like to start off with a simple command to insert a external drawing and from that add options you want and tie in with your form or palette?

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #37 on: March 31, 2011, 09:38:11 AM »
Dim curdb As Database = doc.Database

  Dim db As Database = doc.Database
            Using db
               db.ReadDwgFile(path, System.IO.FileShare.Read, True, "")


Just looking real quick you are using the same database from whatever doc is passed in as a parameter
You need to create a new database before you call ReadDwgFile

Ok, I'm working on doing the 'reverse integration' as you suggested. One thing I don't get is the comment above. Why do I need to create a new database when, as in the above example, I just created one? That doesn't make any sense to me at all. I must be missing something here... again.  :oops: And what does the doc passed to the routine have to do with it?
« Last Edit: March 31, 2011, 10:36:18 AM by Patch61 »

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #38 on: March 31, 2011, 11:07:29 AM »
I do not see CurDoc declared, but who cares.

Would like to start off with a simple command to insert a external drawing and from that add options you want and tie in with your form or palette?

Yes, I would like to start off with a simple command to insert an external drawing. Right now, all I can do is copy what I have, which already has problems.

<rant>
The biggest problem I have with AutoCAD's .Net API is the very crappy documentation. This has to be the worst API documentation I've ever had to use. I've tried to look up how to insert a block and found nothing. Same for inserting a drawing as a block. Where are the step by step instructions? Where is the example? All I can find is technobabble that refers to other technobabble. It is only really useful if you already understand it.
</rant>

Thanks,
Steve
« Last Edit: March 31, 2011, 11:18:55 AM by Patch61 »

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #39 on: March 31, 2011, 07:23:58 PM »
Sorry I have been busy or actually sleeping and hanging with kid I will post example later tonight with hopefully good enough notes to understand.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Trying to insert block in current UCS
« Reply #40 on: March 31, 2011, 07:31:04 PM »

Steve,
Have a work through this.
It is a work in progress and have all your answers in due course.

http://www.theswamp.org/index.php?topic=37686.msg427185#new
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #41 on: April 01, 2011, 01:07:08 AM »
As Kerry posted he has started a great thread that will help more than this.


Quote
Option strict *is* off... Directcast is something I know NOTHING about, anyway. I got that from somebody's example or a conversion from C#.
C# does not allow implicit conversion if it is a narrowing conversion. With VB if option strict is off it will allow a narrow conversion.
So using a tool to convert C# to VB can add DirectCast()-- which basically succeeds if the 2 types have a inheritance relationship and is more efficient than CType()

Why do I need to create a new database when, as in the above example, I just created one?
Not sure what new one was created? Both are assigned to the Database of the Document passed into your function.
Dim curdb As Database = doc.Database
Dim db As Database = doc.Database

Quote
Yes, I would like to start off with a simple command to insert an external drawing

This is copied from here http://forums.augi.com/showthread.php?t=126483

Hopefully if you have any questions someone will explain it to you.
Basically Insert a drawing as a block into current drawing then create and insert a new blockreference from it.
So please ask any questions if do not understand what the code is doing

Code: [Select]
<CommandMethod("InsertDwg")> _
        Public Sub InsertDwg()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim fname As String = "C:\Users\Jeff\Documents\Drawing1.dwg"
            Dim ObjId As ObjectId
            Using trx As Transaction = db.TransactionManager.StartTransaction
                Dim bt As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
                Dim btrMs As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)
                Using dbInsert As New Database(False, True)
                    dbInsert.ReadDwgFile(fname, IO.FileShare.Read, True, "")
                    ObjId = db.Insert(Path.GetFileNameWithoutExtension(fname), dbInsert, True)
                End Using
                Dim ppo As New PromptPointOptions(vbCrLf & "Insertion Point")
                Dim ppr As PromptPointResult
                ppr = ed.GetPoint(ppo)
                If ppr.Status <> PromptStatus.OK Then
                    ed.WriteMessage(vbCrLf & "You decided to QUIT!")
                    Exit Sub
                End If
                Dim insertPt As Point3d = ppr.Value
                Dim bref As New BlockReference(insertPt, ObjId)
                btrMs.AppendEntity(bref)
                trx.AddNewlyCreatedDBObject(bref, True)
                trx.Commit()
            End Using

        End Sub

Patch61

  • Guest
Re: Trying to insert block in current UCS
« Reply #42 on: April 01, 2011, 10:44:45 AM »

Steve,
Have a work through this.
It is a work in progress and have all your answers in due course.

http://www.theswamp.org/index.php?topic=37686.msg427185#new


Kerry,

Great thread! It's a shame AutoDesk didn't give us anything like that, But I am soooo grateful for your assistance and sample code. If I could buy you a drink, I would.


Gile and JeffH,

Thanks for all your help and codes. I don't know what I would have done without your assistance (probably pulled out lots of my few remaining hairs).


You guys will be happy to know that my routine seems to be working and doing everything I need it to. Woot!

If either of you guys ever come to Orlando and want to see Disney, be sure to hit me up. My wife works there and we enjoy a number of perks from that and I wouldn't mind sharing (the perks, not my wife  :-o :-D).

Thanks again, guys!
« Last Edit: April 01, 2011, 11:17:13 AM by Patch61 »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Trying to insert block in current UCS
« Reply #43 on: April 01, 2011, 10:20:41 PM »
< .. > grateful for your assistance and sample code. If I could buy you a drink, I would.


< .. >
You're welcome Steve.
It's a bit far for me to travel to collect  :-D

In the mean time, I know Mark would appreciate some monetary assistance to maintain the site so we can play here :).

Regards
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

TJK44

  • Newt
  • Posts: 196
Re: Trying to insert block in current UCS
« Reply #44 on: December 20, 2011, 06:40:31 PM »
Has anyone got the insert to work with a file that contains only xrefs? It does bring in the file, but in the xref manager all the xrefs are Unresolved. I am forced to right click in the status column and select Reload All References. I went through and debugged and it appears it is actually bring in the xrefs at this line. Could anyone give me some advice as to what I am missing. I'll post the entire code I am using.

Code: [Select]
ObjId = db.Insert(Path.GetFileNameWithoutExtension(fname), dbInsert, True)

Code: [Select]
<CommandMethod("ImportPart")> _
Public Sub ImportPart()

                Dim fname As String = "R:\TEST\X-REF MASTER FILES\000022-01-01 TEST\000022-01-01 test drawing.dwg"


                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim db As Database = doc.Database
                Dim ed As Editor = doc.Editor
                'Dim fname As String = "C:\Users\Jeff\Documents\Drawing1.dwg"
                Dim ObjId As ObjectId
                Using trx As Transaction = db.TransactionManager.StartTransaction
                    Using docLoc As DocumentLock = doc.LockDocument
                        Dim bt As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
                        Dim btrMs As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)
                        Using dbInsert As New Database(False, True)
                            dbInsert.ReadDwgFile(fname, IO.FileShare.Read, False, "")
                            ObjId = db.Insert(Path.GetFileNameWithoutExtension(fname), dbInsert, True)
                        End Using
                        Dim ppo As New PromptPointOptions(vbCrLf & "Insertion Point")
                        Dim ppr As PromptPointResult
                        ppr = ed.GetPoint(ppo)
                        If ppr.Status <> PromptStatus.OK Then
                            ed.WriteMessage(vbCrLf & "You decided to QUIT!")
                            Exit Sub
                        End If
                        Dim insertPt As Point3d = ppr.Value
                        Dim bref As New BlockReference(insertPt, ObjId)
                        btrMs.AppendEntity(bref)
                        trx.AddNewlyCreatedDBObject(bref, True)

                        trx.Commit()
                        bref.ExplodeToOwnerSpace()


                    End Using
                End Using
            End If

        Catch ex As Exception

        End Try
    End Sub

Thanks,

Ted

Jeff H

  • Needs a day job
  • Posts: 6075
Re: Trying to insert block in current UCS
« Reply #45 on: December 20, 2011, 07:01:01 PM »
The exact same behavior happens if you do it through the UI.
 
Maybe call
Database.ReloadXrefs

kaefer

  • Swamp Rat
  • Posts: 572
Re: Trying to insert block in current UCS
« Reply #46 on: December 20, 2011, 07:07:23 PM »
Maybe call
Database.ReloadXrefs

Quote
Database.ReloadXrefs Method

Description

This function reloads the xrefs whose BlockTableRecord ObjectIds are in xrefIds

Quote
Database.ResolveXrefs Method

Description

This function resolves existing xrefs in the working database.

TJK44

  • Newt
  • Posts: 196
Re: Trying to insert block in current UCS
« Reply #47 on: December 21, 2011, 10:14:15 AM »
Thank you kaefer and Jeff! I modified my code to use Database.ResolveXrefs and it reloaded the new ones. Here is the new code.

Code: [Select]
<CommandMethod("ImportPart")> _
Public Sub ImportPart()

                Dim fname As String = "R:\TEST\X-REF MASTER FILES\000022-01-01 TEST\000022-01-01 test drawing.dwg"


                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim db As Database = doc.Database
                Dim ed As Editor = doc.Editor
                'Dim fname As String = "C:\Users\Jeff\Documents\Drawing1.dwg"
                Dim ObjId As ObjectId
                Using trx As Transaction = db.TransactionManager.StartTransaction
                    Using docLoc As DocumentLock = doc.LockDocument
                        Dim bt As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
                        Dim btrMs As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)
                        Using dbInsert As New Database(False, True)
                            dbInsert.ReadDwgFile(fname, IO.FileShare.Read, False, "")
                            ObjId = db.Insert(Path.GetFileNameWithoutExtension(fname), dbInsert, True)
                        End Using
                        Dim ppo As New PromptPointOptions(vbCrLf & "Insertion Point")
                        Dim ppr As PromptPointResult
                        ppr = ed.GetPoint(ppo)
                        If ppr.Status <> PromptStatus.OK Then
                            ed.WriteMessage(vbCrLf & "You decided to QUIT!")
                            Exit Sub
                        End If
                        Dim insertPt As Point3d = ppr.Value
                        Dim bref As New BlockReference(insertPt, ObjId)
                        btrMs.AppendEntity(bref)
                        trx.AddNewlyCreatedDBObject(bref, True)

                        trx.Commit()
                        bref.ExplodeToOwnerSpace()
                       
                        #############################
                        db.ResolveXrefs(False, False)
                        #############################

                    End Using
                End Using
            End If

        Catch ex As Exception

        End Try
    End Sub