Author Topic: Xref multiple times with one dwg file  (Read 5057 times)

0 Members and 1 Guest are viewing this topic.

TJK44

  • Newt
  • Posts: 196
Xref multiple times with one dwg file
« on: November 17, 2011, 10:59:31 AM »
I have wrote this command that wblocks out each block to a parts folder and then I xref each of these parts back in to an empty dwg file. It works fine, but noticed that if there is more than one block with the same name, the new dwg only shows the last block that was added to the parts folder with that name. Do i have to cycle through each block and assign the block name plus an incrementing number, or is there a way with one block in this folder to automatically xref it back each time it was present on the previous drawing? The purpose of this is to generate a clean drawing file from the old one that could have a bunch of stuff we don't need. Currently I am creating a folder called xrefs inside the parts folder and cycling through each wblock and incrementing a number at the end. Would like to not have to do that seeing it just will take up a lot of extra storage.

Thanks for any help,

Ted
« Last Edit: November 17, 2011, 11:08:53 AM by TJK44 »

TJK44

  • Newt
  • Posts: 196
Re: Xref multiple times with one dwg file
« Reply #1 on: November 18, 2011, 09:09:35 AM »
In addition to what I had posted, it seems like if I xref the same dwg more than once, the one that was referenced before gets replaced by the next one and so on. The position of each xref is different. Anyone have an idea as to why each time I xref the same dwg the other one would get replaced?

**UPDATE
It appears that the xrefobjID is getting the same objectID each time it reads that file to xref, so that is why it is replacing the files that are already xreferenced in the drawing. Is there anyway around this?
« Last Edit: November 18, 2011, 09:22:06 AM by TJK44 »

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: Xref multiple times with one dwg file
« Reply #2 on: November 18, 2011, 10:27:34 AM »
Are you using the same name when adding it to the drawing?

I.E. db.OverlayXref(filepath, XrefName);
Revit 2019, AMEP 2019 64bit Win 10

TJK44

  • Newt
  • Posts: 196
Re: Xref multiple times with one dwg file
« Reply #3 on: November 18, 2011, 10:33:23 AM »
Yes, does that have to be unique each time or it will generate a the same ID? Here is what I have for that line of code

Code: [Select]
Dim xrefObjId As ObjectId = xrefdb.AttachXref(file, Path.GetFileNameWithoutExtension(file))

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: Xref multiple times with one dwg file
« Reply #4 on: November 18, 2011, 10:43:13 AM »
Yes, that has to be unique.
Revit 2019, AMEP 2019 64bit Win 10

TJK44

  • Newt
  • Posts: 196
Re: Xref multiple times with one dwg file
« Reply #5 on: November 18, 2011, 10:48:17 AM »
I tried to increment a number after the blockname and in the xref manager it said i had three different xrefs, but still only wound up with one drawing. What I want to do is only see 1 xref for all three of the drawing with the same block name. Here is the entire code I am working with if you or anyone could offer any suggestions. Thanks.

Code: [Select]
        <CommandMethod("CreateMasterDWG")> _
        Public Sub newBlock()
            Dim document As Document = Application.DocumentManager.MdiActiveDocument
            Dim editor As Editor = document.Editor
            Dim database As Database = document.Database

            Dim fName2 As String = database.Filename
            If fName2 = "" Then
                Exit Sub
            End If
            Dim curdir2 As String = Path.GetDirectoryName(fName2)
            Dim db As Database = New Database(True, False)
            Dim i As Integer = 1
            Dim frm1 As New Form1
            Dim strFileName As String
            frm1.SaveFileDialog1.InitialDirectory = curdir2
            frm1.SaveFileDialog1.Title = "Select a location to save the master file."
            frm1.SaveFileDialog1.Filter = "Drawing Files|*.dwg"
            frm1.SaveFileDialog1.AddExtension = True

            If frm1.SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
                strFileName = frm1.SaveFileDialog1.FileName
                Dim xrefPath As String = strFileName
            Else
                Exit Sub
            End If

            Using trans As Transaction = db.TransactionManager.StartTransaction()
                db.SaveAs(strFileName, DwgVersion.Newest)
            End Using
            Dim xrefdb As Database = New Database(False, False)
            xrefdb.ReadDwgFile(strFileName, FileShare.ReadWrite, False, "")

            Dim oidc As New ObjectIdCollection()
            Try
                Using trans As Transaction = database.TransactionManager.StartTransaction()
                    Dim btr As BlockTable = DirectCast(trans.GetObject(database.BlockTableId, OpenMode.ForRead), BlockTable)
                    Dim btrMs As BlockTableRecord = TryCast(btr(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead), BlockTableRecord)
                    'Dim i As Integer = 0
                    Dim partnum As String = ""
                    'go through each object in the block table record
                    For Each entID As ObjectId In btrMs
                        'create the objectIDCollection used to create the wblock
                        Dim oidc2 As New ObjectIdCollection()
                        'create variable used to determine is it is a block reference
                        Dim ent As Entity = trans.GetObject(entID, OpenMode.ForRead, False)
                        'if it is a block then perform code below
                        If TypeOf ent Is BlockReference Then
                            'since it is a block, add to the IDcollection
                            oidc2.Add(entID)
                            Dim blkRef As BlockReference = TryCast(trans.GetObject(entID, OpenMode.ForRead, False), BlockReference)
                            Dim attRefIds As AttributeCollection = blkRef.AttributeCollection

                            'cycle through the attributes associated with the current block
                            For Each attrefid As ObjectId In attRefIds
                                Dim attref As AttributeReference = trans.GetObject(attrefid, OpenMode.ForRead, False)

                                Select Case attref.Tag
                                    'if block has attribute project ID then create the wblock
                                    Case "Part Number"
                                        'create string with partnum

                                        Dim strPartNum As String = attref.TextString

                                        Dim DestData As New Database(True, False)

                                        Using document.LockDocument()
                                            Using transNewDb As Transaction = DestData.TransactionManager.StartTransaction()
                                                Dim bt As BlockTable = TryCast(transNewDb.GetObject(DestData.BlockTableId, OpenMode.ForRead), BlockTable)
                                                Dim IDMap As New IdMapping()
                                                DestData.WblockCloneObjects(oidc2, bt(BlockTableRecord.ModelSpace), IDMap, DuplicateRecordCloning.Replace, False)
                                                transNewDb.Commit()

                                                Dim fName As String = database.Filename
                                                Dim curdir As String = Path.GetDirectoryName(fName)

                                                If Not Directory.Exists(curdir & "\parts") Then
                                                    Directory.CreateDirectory(curdir & "\parts")
                                                End If
                                                Directory.CreateDirectory(curdir & "\parts\xrefs")
                                                DestData.SaveAs(curdir & "\parts\" & strPartNum & ".dwg", DwgVersion.Newest)
                                                DestData.SaveAs(curdir & "\parts\xrefs\" & strPartNum & ".dwg", DwgVersion.Newest)
                                                Dim strPartFile As String = curdir & "\parts\" & strPartNum & ".dwg"
                                                'CreateXrefMaster(strFileName, strPartFile)

                                                Using trx As Transaction = xrefdb.TransactionManager.StartTransaction()
                                                    Dim xrefBt As BlockTable = trx.GetObject(xrefdb.BlockTableId, OpenMode.ForWrite)
                                                    Dim btrMs2 As BlockTableRecord = trx.GetObject(xrefBt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                                                    Dim file As String = strPartFile
                                                    'list the names of all files in the specified directory

                                                    Dim xrefObjId As New ObjectId

                                                    xrefObjId = xrefdb.AttachXref(file, Path.GetFileNameWithoutExtension(file))

                                                    Dim bref As New BlockReference(Point3d.Origin, xrefObjId)

                                                    btrMs2.AppendEntity(bref)

                                                    trx.AddNewlyCreatedDBObject(bref, True)

                                                    trx.Commit()


                                                End Using

                                            End Using
                                        End Using


                                End Select

                            Next

                        End If
                       
                    Next

                End Using

                xrefdb.SaveAs(strFileName, DwgVersion.Newest)

            Catch ex As System.Exception
                Windows.MessageBox.Show("Error occurred: " & ex.Message, "Error", Windows.MessageBoxButton.OK, Windows.MessageBoxImage.Error)
            End Try
        End Sub

Jeff H

  • Needs a day job
  • Posts: 6055
Re: Xref multiple times with one dwg file
« Reply #6 on: November 18, 2011, 10:49:03 AM »
Have you tried to Xref the drawing once then insert as many BlockReference's as needed using the xref's BlockTableRecord?

TJK44

  • Newt
  • Posts: 196
Re: Xref multiple times with one dwg file
« Reply #7 on: November 18, 2011, 10:53:47 AM »
I'm sorry, I kind of understand what you are saying Jeff. Do you mean after it creates the first xref, if it sees another block with the same name that was already xreferenced then use the xref that is already in the btr and give it the coordinates of the block?

Jeff H

  • Needs a day job
  • Posts: 6055
Re: Xref multiple times with one dwg file
« Reply #8 on: November 18, 2011, 11:52:53 AM »
I'm sorry, I kind of understand what you are saying Jeff.
No need to apologize as I rarely understand what I am saying either.
What I want to do is only see 1 xref for all three of the drawing with the same block name.
I think I am confused on the intent, sorry about that.
 
 
 

TJK44

  • Newt
  • Posts: 196
Re: Xref multiple times with one dwg file
« Reply #9 on: November 18, 2011, 11:57:48 AM »
Well I got all the correct xrefs showing on the new file it is creating. Now my only problem is they are not showing up at the correct positions when I open the drawing. I changed the position for the blockreference that is creating the xref each time and that seemed to bring in each of the xrefs. I'll keep playing with it, seems I am getting closer. Here is my code now if anyone would like to give any input. Thanks.

Quote
I think I am confused on the intent, sorry about that.
What I am trying to do is basically clean up a drawing. I am searching a drawing for blocks that contain the attribute Part Number. If it does I am wblocking each of them and then want to xref whatever blocks it found that had a part number attribute into a new drawing.

Code: [Select]
        <CommandMethod("CreateMasterDWG")> _
        Public Sub newBlock()
            Dim document As Document = Application.DocumentManager.MdiActiveDocument
            Dim editor As Editor = document.Editor
            Dim database As Database = document.Database

            Dim fName2 As String = database.Filename
            If fName2 = "" Then
                Exit Sub
            End If
            Dim curdir2 As String = Path.GetDirectoryName(fName2)
            Dim db As Database = New Database(True, False)
            Dim i As Integer = 1
            Dim frm1 As New Form1
            Dim strFileName As String
            frm1.SaveFileDialog1.InitialDirectory = curdir2
            frm1.SaveFileDialog1.Title = "Select a location to save the master file."
            frm1.SaveFileDialog1.Filter = "Drawing Files|*.dwg"
            frm1.SaveFileDialog1.AddExtension = True

            If frm1.SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
                strFileName = frm1.SaveFileDialog1.FileName
                Dim xrefPath As String = strFileName
            Else
                Exit Sub
            End If

            Using trans As Transaction = db.TransactionManager.StartTransaction()
                db.SaveAs(strFileName, DwgVersion.Newest)
            End Using
            Dim xrefdb As Database = New Database(False, False)
            xrefdb.ReadDwgFile(strFileName, FileShare.ReadWrite, False, "")

            Dim oidc As New ObjectIdCollection()
            Try
                Using trans As Transaction = database.TransactionManager.StartTransaction()
                    Dim btr As BlockTable = DirectCast(trans.GetObject(database.BlockTableId, OpenMode.ForRead), BlockTable)
                    Dim btrMs As BlockTableRecord = TryCast(btr(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead), BlockTableRecord)
                    'Dim i As Integer = 0
                    Dim partnum As String = ""
                    'go through each object in the block table record
                    For Each entID As ObjectId In btrMs
                        'create the objectIDCollection used to create the wblock
                        Dim oidc2 As New ObjectIdCollection()
                        'create variable used to determine is it is a block reference
                        Dim ent As Entity = trans.GetObject(entID, OpenMode.ForRead, False)
                        'if it is a block then perform code below
                        If TypeOf ent Is BlockReference Then
                            'since it is a block, add to the IDcollection
                            oidc2.Add(entID)
                            Dim blkRef As BlockReference = TryCast(trans.GetObject(entID, OpenMode.ForRead, False), BlockReference)
                            Dim attRefIds As AttributeCollection = blkRef.AttributeCollection

                            'cycle through the attributes associated with the current block
                            For Each attrefid As ObjectId In attRefIds
                                Dim attref As AttributeReference = trans.GetObject(attrefid, OpenMode.ForRead, False)

                                Select Case attref.Tag
                                    'if block has attribute project ID then create the wblock
                                    Case "Part Number"
                                        'create string with partnum

                                        Dim strPartNum As String = attref.TextString

                                        Dim DestData As New Database(True, False)

                                        Using document.LockDocument()
                                            Using transNewDb As Transaction = DestData.TransactionManager.StartTransaction()
                                                Dim bt As BlockTable = TryCast(transNewDb.GetObject(DestData.BlockTableId, OpenMode.ForRead), BlockTable)
                                                Dim IDMap As New IdMapping()
                                                DestData.WblockCloneObjects(oidc2, bt(BlockTableRecord.ModelSpace), IDMap, DuplicateRecordCloning.Replace, False)
                                                transNewDb.Commit()

                                                Dim fName As String = database.Filename
                                                Dim curdir As String = Path.GetDirectoryName(fName)

                                                If Not Directory.Exists(curdir & "\parts") Then
                                                    Directory.CreateDirectory(curdir & "\parts")
                                                End If
                                                Directory.CreateDirectory(curdir & "\parts\xrefs")
                                                DestData.SaveAs(curdir & "\parts\" & strPartNum & ".dwg", DwgVersion.Newest)
                                                DestData.SaveAs(curdir & "\parts\xrefs\" & strPartNum & ".dwg", DwgVersion.Newest)
                                                Dim strPartFile As String = curdir & "\parts\" & strPartNum & ".dwg"
                                                'CreateXrefMaster(strFileName, strPartFile)

                                                Using trx As Transaction = xrefdb.TransactionManager.StartTransaction()
                                                    Dim xrefBt As BlockTable = trx.GetObject(xrefdb.BlockTableId, OpenMode.ForWrite)
                                                    Dim btrMs2 As BlockTableRecord = trx.GetObject(xrefBt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                                                    Dim coords As Point3d = blkRef.Position()

                                                    Dim file As String = strPartFile
                                                    'list the names of all files in the specified directory

                                                    Dim xrefObjId As New ObjectId

                                                    xrefObjId = xrefdb.AttachXref(file, Path.GetFileNameWithoutExtension(file))

                                                    Dim bref As New BlockReference(coords, xrefObjId)

                                                    btrMs2.AppendEntity(bref)

                                                    trx.AddNewlyCreatedDBObject(bref, True)

                                                    trx.Commit()

                                                    xrefdb.SaveAs(strFileName, DwgVersion.Newest)

                                                End Using

                                            End Using
                                        End Using


                                End Select

                            Next

                        End If
                       
                    Next

                End Using
                Directory.Delete(curdir2 & "\parts\xrefs", True)


            Catch ex As System.Exception
                Windows.MessageBox.Show("Error occurred: " & ex.Message, "Error", Windows.MessageBoxButton.OK, Windows.MessageBoxImage.Error)
            End Try
        End Sub
« Last Edit: November 18, 2011, 12:03:57 PM by TJK44 »

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: Xref multiple times with one dwg file
« Reply #10 on: November 21, 2011, 08:28:23 AM »
If I'm understanding correctly, your trying to insert the same drawing as an Xref but in a different location like you would a block?
Revit 2019, AMEP 2019 64bit Win 10

TJK44

  • Newt
  • Posts: 196
Re: Xref multiple times with one dwg file
« Reply #11 on: November 21, 2011, 08:52:27 AM »
Yes, I am generating a dwg file with wblock and then would like to create a new empty drawing and xref the file. The problem I am having is when a block is referenced more than once. The block is in the drawing correctly, but they are not in the correct position. If I'm going through a drawing and wblocking each block and then doing an xref it will show up in the new drawing but they will be on top of each other. An example would be I had 4 of the same part on the drawing and then I run this and the 4 parts will be on top of each other instead of having the correct position and rotation.
« Last Edit: November 21, 2011, 09:17:38 AM by TJK44 »

Jeff H

  • Needs a day job
  • Posts: 6055
Re: Xref multiple times with one dwg file
« Reply #12 on: November 21, 2011, 11:07:01 AM »
I think some of the confusion is you are using xref to mean a BlockReference.
 
Here are some 'loose' definitions

Xref----A BlockTableRecord that is mapped to anoter Drawing. You will never see a xref in a drawing.

BlockReference---- A 'Insert' that is a graphical representation of a BlockTableRecord which can have its own scale, InsertionPoint(wich transform all objects from its orgin definition), etc.....
 

TJK44

  • Newt
  • Posts: 196
Re: Xref multiple times with one dwg file
« Reply #13 on: November 21, 2011, 11:10:38 AM »
Sorry you're right Jeff. I am trying to use blockreferences in my situation. Do you still use db.AttachXRef to reference a block in a drawing?

Jeff H

  • Needs a day job
  • Posts: 6055
Re: Xref multiple times with one dwg file
« Reply #14 on: November 21, 2011, 11:21:15 AM »
You use AttachXRef once and  AttachXRef will return a ObjectId of the newly created BlockTableRecord.

Then you can create as my BlockReference's as you want passing in the ObjectId to the BlockReference's second argument in its constructor.