Author Topic: How to immitate wblock command  (Read 9517 times)

0 Members and 1 Guest are viewing this topic.

Irvin

  • Guest
How to immitate wblock command
« on: November 28, 2011, 01:10:32 PM »
Hello,

How can i imitate the autocad wblock command.

When you use wblock in AutoCAD you can choose if you want wblock a block or the entire drawing. I need to wblock a block.
So that the entity's from a block are stored in a new dwg file. Witch hold the same properties as the blocktablerecord. Example:
if a blocktablerecord is annotative the new dwg should be an isannotativedwg is true. The blocktablerecord should be the new dwg.
I don't want to create a new dwg with a block in it.

Sorry for the bad description but i think you guys understand my question.

Kind regards,

Irvin

Jeff H

  • Needs a day job
  • Posts: 6151
Re: How to immitate wblock command
« Reply #1 on: November 28, 2011, 01:27:47 PM »
The Wblock command is a type of save command.
 
I might be wrong but I think you must create a new or overwrite a existing file.
 
Are you wanting to WblockCloneObjects into a existing drawing and save it?
 

Irvin

  • Guest
Re: How to immitate wblock command
« Reply #2 on: November 28, 2011, 01:33:38 PM »
If you run wblock and you set the radiobutton to block you can choose a block from the blocktable.
On the form you can specify a blockname.dwg and the location where you want to store the new dwg file.

The newly createfile (dwg) should have te same properties when you get the blocktable record.

Do you understand?
 
« Last Edit: November 28, 2011, 01:37:19 PM by Irvin »

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: How to immitate wblock command
« Reply #3 on: November 28, 2011, 03:09:38 PM »
Hi,

Here's a little snippet

Code: [Select]
        private void WBlock(string blockName, string fileName)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            ObjectIdCollection idCol = new ObjectIdCollection();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (!bt.Has(blockName)) return;
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead);
                foreach (ObjectId id in btr)
                {
                    idCol.Add(id);
                }
            }
            using(Database newDb = new Database())
            using (Transaction tr = newDb.TransactionManager.StartTransaction())
            {
                BlockTable newBt = (BlockTable)tr.GetObject(newDb.BlockTableId, OpenMode.ForRead);
                IdMapping idMap = new IdMapping();
                db.WblockCloneObjects(idCol, newBt[BlockTableRecord.ModelSpace], idMap, DuplicateRecordCloning.Ignore, false);
                tr.Commit();
                newDb.SaveAs(fileName, DwgVersion.Current);
            }
        }
Speaking English as a French Frog

fixo

  • Guest
Re: How to immitate wblock command
« Reply #4 on: November 28, 2011, 03:43:04 PM »
If you run wblock and you set the radiobutton to block you can choose a block from the blocktable.
On the form you can specify a blockname.dwg and the location where you want to store the new dwg file.

The newly createfile (dwg) should have te same properties when you get the blocktable record.

Do you understand?
Here is my 2 c, not tested enough:
Code: [Select]
        Public Sub CreateEmptyDwg(ByVal dwgpath As String)
            Try
                Dim db As New Database(True, True)
                db.SaveAs(dwgpath, DwgVersion.Newest)
                db.CloseInput(True)
            Catch ex As System.Exception
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message)
            End Try
        End Sub

        <CommandMethod("MWBLOCK", CommandFlags.Session)> _
        Public Sub WblockingBlock()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            Dim dwgpath As String = ""
            Dim oidc As New ObjectIdCollection()
            Try
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                    Dim btr As BlockTableRecord = TryCast(bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead), BlockTableRecord)
                    Dim bname As String = ed.GetString(vbCrLf + "Block name: ").StringResult
                    If bt.Has(bname) Then
                        Dim fold As String = ed.GetString(vbCrLf + "Enter folder name: ").StringResult
                        dwgpath = Path.Combine(fold, bname + ".dwg")
                        If Not File.Exists(dwgpath) Then
                            CreateEmptyDwg(dwgpath)
                        End If
                    End If
                    If Not File.Exists(dwgpath) Then
                        Return
                    End If
                    Dim blkId As ObjectId = bt(bname)
                    oidc.Add(blkId)
                    tr.Commit()
                End Using

                Using newdb As New Database

                    newdb.ReadDwgFile(dwgpath, FileOpenMode.OpenForReadAndWriteNoShare, False, "")
                   
                    Using newtr As Transaction = newdb.TransactionManager.StartTransaction()
                        Dim IDMap As New IdMapping()
                        db.WblockCloneObjects(oidc, newdb.BlockTableId, IDMap, DuplicateRecordCloning.Replace, False)
                        'here you insert this block in 0,0,0 point  usual way (it's already in the BlockTable now)
                        newtr.Commit()
                    End Using
                    newdb.SaveAs(dwgpath, DwgVersion.Current) 'A2009-working
                    'newdb.SaveAs(dwgpath, DwgVersion.Current,newdb.SecurityParameters)'<--A2010?
                End Using
            Catch ex As System.Exception
                ed.WriteMessage(ex.ToString() + vbCrLf + ex.StackTrace)
            Finally

            End Try
        End Sub

Irvin

  • Guest
Re: How to immitate wblock command
« Reply #5 on: November 29, 2011, 03:47:10 PM »
Hi all,

Gile, Fixo thanks for both of your codesamples. I've got it up an running. The only thing i needed to add was a check is the btr was annotative and set the propertie of the new dwg is annotativedwg true or false. Thanks again for your help it's verry much appreciated.

Kind regards,

Irvin

Irvin

  • Guest
Re: How to immitate wblock command
« Reply #6 on: December 08, 2011, 07:39:42 AM »
Hello everybody,

I've updated the code because this wasn't working for dynamicblocks.
Here's a code snippet the realy immitates the AutoCAD wblock command.

It's even simpler then we (I) tought.

Code: [Select]
[CommandMethod("MyWblockCommand")]
public void MyWblockCommand()
{
    Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
    Editor ed = doc.Editor;
    Database db = doc.Database;

    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
        BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

        using (Database tempDb = db.Wblock(bt["<any blockname within the drawing>"]))
        {
           tempDb.SaveAs("c:\\temp\\BlockToDwg.dwg", true, DwgVersion.Newest, tempDb.SecurityParameters);
        }       
        trans.Commit();
    }
}

Hope it helps someone else.

Best regards,

Irvin
« Last Edit: December 08, 2011, 07:47:24 AM by Irvin »

TJK44

  • Guest
Re: How to immitate wblock command
« Reply #7 on: February 16, 2012, 08:55:07 AM »
I have been playing around with Irvin's last bit of code here to wblock. However, is there a way to do exactly what the wblock command does except not have the block in the new drawing become exploded?

kaefer

  • Guest
Re: How to immitate wblock command
« Reply #8 on: February 16, 2012, 09:14:49 AM »
I have been playing around with Irvin's last bit of code here to wblock. However, is there a way to do exactly what the wblock command does except not have the block in the new drawing become exploded?

Матрёшка alert! That wouldn't be the WBLOCK command, but something along the lines of a hypothecal CREATENESTEDBLOCK command.  Roughly:
  • Select BlockReference
  • Create side database
  • WblockCloneObjects the BlockReference into the target's model space
  • SaveAs side database

TJK44

  • Guest
Re: How to immitate wblock command
« Reply #9 on: February 16, 2012, 09:29:13 AM »
What I'm trying to make happen is I want the new drawing file to look the exact same as what the wblock command does. Meaning, when wblocking out a block that has been rotated or anything it takes away the rotation and other properties (i think) and puts it at point 0,0,0. Wblockcloneobjects maintains all the properties of the block.

TJK44

  • Guest
Re: How to immitate wblock command
« Reply #10 on: February 16, 2012, 09:56:49 AM »
Trying something like this to maybe change the block properties to all zeros? oidc2 will always only have one block objectid in it.

Code: [Select]
Dim destData As New Database(True, False)
                                            Using transNewDb As Transaction = destData.TransactionManager.StartTransaction()
                                                Dim bt As BlockTable = TryCast(transNewDb.GetObject(destData.BlockTableId, OpenMode.ForRead), BlockTable)
                                                Dim btrMs2 As BlockTableRecord = TryCast(bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead), BlockTableRecord)
                                                Dim idmap As New IdMapping
                                                'destData.WblockCloneObjects(oidc2, bt(BlockTableRecord.ModelSpace), idmap, DuplicateRecordCloning.Replace, False)

                                                database.Wblock(destData, oidc2, New Point3d(0, 0, 0), DuplicateRecordCloning.Ignore)
                                                'go through each object in the block table record
                                                For Each entID2 As ObjectId In btrMs2
                                                    'create variable used to determine is it is a block reference
                                                    Dim ent2 As Entity = transNewDb.GetObject(entID2, OpenMode.ForRead, False)
                                                    'if it is a block then perform code below
                                                    If TypeOf ent2 Is BlockReference Then
                                                        Dim blkRef2 As BlockReference = TryCast(transNewDb.GetObject(entID2, OpenMode.ForWrite, False), BlockReference)
                                                        blkRef2.Position = New Point3d(0, 0, 0)
                                                        blkRef2.Rotation = 0
                                                    End If
                                                Next
                                                transNewDb.Commit()
                                                destData.SaveAs(strSaveDir & "\" & strFileDir & " - parts\" & strBlockName & ".dwg", DwgVersion.Newest)
                                                ok = True
                                            End Using


This seems to do what I want...

Code: [Select]
Dim destData As New Database(True, False)
                                            Using transNewDb As Transaction = destData.TransactionManager.StartTransaction()
                                                Dim bt As BlockTable = TryCast(transNewDb.GetObject(destData.BlockTableId, OpenMode.ForRead), BlockTable)
                                                Dim btrMs2 As BlockTableRecord = TryCast(bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead), BlockTableRecord)
                                                Dim idmap As New IdMapping
                                                'destData.WblockCloneObjects(oidc2, bt(BlockTableRecord.ModelSpace), idmap, DuplicateRecordCloning.Replace, False)

                                                database.Wblock(destData, oidc2, New Point3d(0, 0, 0), DuplicateRecordCloning.Ignore)
                                                'go through each object in the block table record
                                                For Each entID2 As ObjectId In btrMs2
                                                    'create variable used to determine is it is a block reference
                                                    Dim ent2 As Entity = transNewDb.GetObject(entID2, OpenMode.ForRead, False)
                                                    'if it is a block then perform code below
                                                    If TypeOf ent2 Is BlockReference Then
                                                        Dim blkRef2 As BlockReference = TryCast(transNewDb.GetObject(entID2, OpenMode.ForWrite, False), BlockReference)
                                                        Dim vec As New Vector3d(0, 0, 1)
                                                        blkRef2.Normal = vec
                                                        blkRef2.Position = New Point3d(0, 0, 0)
                                                        blkRef2.Rotation = 0
                                                        blkRef2.ScaleFactors = New Scale3d(0)
                                                    End If
                                                Next
                                                transNewDb.Commit()
                                                destData.SaveAs(strSaveDir & "\" & strFileDir & " - parts\" & strBlockName & ".dwg", DwgVersion.Newest)
                                                ok = True
                                            End Using
« Last Edit: February 16, 2012, 10:33:53 AM by TJK44 »

TJK44

  • Guest
Re: How to immitate wblock command
« Reply #11 on: February 17, 2012, 12:40:32 PM »
Well, after testing this on a couple different drawings it works on some but not others. Anyone have any ideas? Somehow I want to achieve what the wblock command does, but not explode the block because I'm losing attributes associated with the block.

kaefer

  • Guest
Re: How to immitate wblock command
« Reply #12 on: February 17, 2012, 01:25:24 PM »
Well, after testing this on a couple different drawings it works on some but not others.

I was about to congratulate you, alas, apparently you didn't make it completely. The form of the Wblock method which takes a Database as first argument is news to me (interesting). Did you try another form of Wblock (that returns a fresh Database) or the WblockCloneObjects method instead, and what exactly goes wrong?

Somehow I want to achieve what the wblock command does, but not explode the block because I'm losing attributes associated with the block.

That's a good enough reason not to explode a block. Taken in isolation, it's no good reason to wrap it inside another block.

I think the problem here is that you can't state your business requirements in a few simple words, and maybe, if you could somehow structure your problem domain, more people would be able to help you out.

TJK44

  • Guest
Re: How to immitate wblock command
« Reply #13 on: February 17, 2012, 01:52:07 PM »
I have tried wblockcloneobjects, but hasnt worked for what Im trying to accomplish. Which wblock method returns a new database?

In the current drawing session create X number of blocks, each block will have multiple copies in model space (mirrored, 3drotate, rotate, align). The final result I'm looking to achieve is, the user runs a command that exports these blocks into the new drawing and each block will become an xref. The new drawing will contain Only xrefs after the command has been run and will look exactly the same as the original drawing that had only blocks in it. As the command runs and encounters a block, it creates a new drawing file with only this block in it to be used for the xref in the new drawing.

First attachment is the desired output, second attachment is what is happening with current code.
« Last Edit: February 17, 2012, 02:14:01 PM by TJK44 »

TheMaster

  • Guest
Re: How to immitate wblock command
« Reply #14 on: February 19, 2012, 01:44:26 AM »
What I think you're describing is what you get by using the 'select objects' form of the WBLOCK command, and selecting a single insertion of the block in model space, that is inserted with all default values (e.g., position = 0,0, scale = 1.0 , rotation = 0.0, etc.).

That should give you want you describe, and be easy to do using WblockCloneObjects().

I have been playing around with Irvin's last bit of code here to wblock. However, is there a way to do exactly what the wblock command does except not have the block in the new drawing become exploded?