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

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Xref multiple times with one dwg file
« Reply #15 on: November 21, 2011, 11:25:37 AM »
Code: [Select]
                Dim xrefId As ObjectId = db.AttachXref("FilePath", "Name of block")
                For i As Integer = 0 To 10
                    Dim xrefBref As New BlockReference(Point3d.Origin, xrefId)
                Next

TJK44

  • Guest
Re: Xref multiple times with one dwg file
« Reply #16 on: November 21, 2011, 11:35:09 AM »
That's what I am doing, but it doesn't put the blockreferences at the correct positions. I'm using Point3d.Origin for the point. Everytime I reference it changes the location of the other blocks that were added previously if the blockreference file changes I think is what is happening.  I tried to increment the number at the end of each block drawing file and then performed the same reference action and it recreated the drawing as I wanted and the block references were all in the correct position. The only problem with this is I don't want those extra files and also, if it's the same part it should only reference one drawing, and not reference a separate drawing per instance of the part.
« Last Edit: November 21, 2011, 11:51:36 AM by TJK44 »

kaefer

  • Guest
Re: Xref multiple times with one dwg file
« Reply #17 on: November 22, 2011, 07:56:53 AM »
... if it's the same part it should only reference one drawing, and not reference a separate drawing per instance of the part.

I'm confused. Based on your message here, you were to loop through the model space trying to replace all block references based only on the occurence of the attribute "Part Number". Please forgive me a couple of remarks:

You don't have Option Strict On], primarily to avoid implicit conversions. Replace them with CType and TryCast instead.

You don't seem to account for case-sensitive string comparison, and spaces in attribute tags are a no-no.

The loop over the AttributeReferences could be made more transparent with Linq's query expressions. If you want to replace one BlockReference with another BlockReference, you could as well keep it and replace its definition (that is the BlockTableRecord property). Taken together, maybe you could make use of this VB.NET code, which tries to illustrate those concerns, including the erasure of the attributes. Xrefs with attributes, anyone?

Code: [Select]
    Public Sub replaceBlock()
        Dim doc = Application.DocumentManager.MdiActiveDocument
        Dim ed = doc.Editor
        Dim db = doc.Database
        Dim ofd =
            New OpenFileDialog(
                "Select drawing to attach",
                Nothing,
                "dwg",
                "DrawingToAttach",
                OpenFileDialog.OpenFileDialogFlags.NoFtpSites)
        If ofd.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
            Exit Sub
        End If
        Dim xName =
            SymbolUtilityServices.GetSymbolNameFromPathName(
                ofd.Filename, "dwg")
        xName =
            SymbolUtilityServices.RepairSymbolName(
                xName, False)
        Dim xBtrId = db.OverlayXref(ofd.Filename, xName)
        Using tr As Transaction = db.TransactionManager.StartTransaction()
            Dim bt = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
            For Each bref In
                From id In CType(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord).Cast(Of ObjectId)()
                Select br = TryCast(tr.GetObject(id, OpenMode.ForRead), BlockReference)
                Where br IsNot Nothing AndAlso _
                    (From id In br.AttributeCollection.Cast(Of ObjectId)()
                     Select ar = TryCast(tr.GetObject(id, OpenMode.ForRead), AttributeReference)
                     Where ar IsNot Nothing) _
                    .FirstOrDefault(Function(attref) attref.Tag.Equals("PartNumber", StringComparison.InvariantCultureIgnoreCase)) _
                    IsNot Nothing
                bref.UpgradeOpen()
                bref.BlockTableRecord = xBtrId
                For Each attref In
                    From id In bref.AttributeCollection.Cast(Of ObjectId)()
                    Select ar = TryCast(tr.GetObject(id, OpenMode.ForWrite), AttributeReference)
                    Where ar IsNot Nothing
                    attref.Erase()
                Next
            Next
            tr.Commit()
        End Using
    End Sub

TJK44

  • Guest
Re: Xref multiple times with one dwg file
« Reply #18 on: November 22, 2011, 08:25:10 AM »
I'm sorry I haven't been as clear as I probably could be. This is the process I am trying to create. Initially a user is going to have a drawing with a bunch of blocks and other entities in it. The purpose of this command is to only select the blocks that have the Part Number attribute, then wblock each of these blocks and then auto populate a new blank drawing file with these blocks that have the part number attribute. So far the code I had posted here http://www.theswamp.org/index.php?topic=40103.msg453886#msg453886 does all of this for me except in the instance the initial drawing has multiples of the same block with the same part number. The new blank drawing is being created and populated, but the positioning of the blocks is not correct. It is xreferencing each of the blocks that contained a part number in the drawing, the problem lies if there is more than one with the exact same part number they appear directly on top of each other.

What I was trying to do was wblock each time it encountered a block with a part number and at the same time attach it as an xref and save the drawing and keep looping through the original drawing. I think the problem is that each time the wblock is rewritten (because it sees a block with the same part number) it is xreferencing it, but it also is changing what xreferences the drawing already has with the same partnumber. I am naming the file "partnumber.dwg". I don't even know if it is possible to do this, because of the xreference file changing it seems it will change what is already xreferenced in the drawing.

I hope that clarifies or makes any sense on what I am trying to accomplish.

Thank you in advance for any help,

Ted

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Xref multiple times with one dwg file
« Reply #19 on: November 22, 2011, 11:37:12 AM »
I think I understand.
If so you might try

1.Iterate the BlockTable looking for BlockTableRecords that contain the AttributeDefinition
2. If it does WBlockCloneObjects the entites fom the BlockTableRecords into a new Drawings modelspace
3.Get a collection insertion points from GetBlockReferenceIds 
4. Xref the new drawing in then insert a new BlockReference at each Postion
 
Is that what you are trying to do?

TJK44

  • Guest
Re: Xref multiple times with one dwg file
« Reply #20 on: November 22, 2011, 11:46:38 AM »
Yes, I think you are understanding what I am trying to do. The problem I am having is dealing with the same block reference more than once from the blocktablerecords. Basically Im trying to add an xref to a blockreference more than once and they all have different insertion points. Right now after it completes, all blockreferences that are the same have the same insertion point and lie on top of each other.

What you have wrote there is what I am aiming for Jeff.

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: Xref multiple times with one dwg file
« Reply #21 on: November 22, 2011, 01:33:37 PM »
Sounds like it would work better if you would bring them in as blocks and not xrefs.  I've never tried bringing in the same file as an xref and just changing its block name and location.  Obviously thats impossible using the ACAD interface and can only be done programatically.  Is there a reason your using Xrefs instead of blocks?

Have you looked at the database with ArxDbg after loading them to confirm there are actually two BlockReferences?
Revit 2019, AMEP 2019 64bit Win 10

TJK44

  • Guest
Re: Xref multiple times with one dwg file
« Reply #22 on: November 22, 2011, 02:16:20 PM »
I haven't looked in the ArxDbg. For the blocks I know that aren't in the correct location if I highlight one a drag it there will be another one underneath it.

They want xrefs so the file size isn't so large.

TJK44

  • Guest
Re: Xref multiple times with one dwg file
« Reply #23 on: November 22, 2011, 02:55:50 PM »
One way to get past this is maybe to wblock and then if it encounters another block with the same part number thats already been wblocked, perform a copy in the new drawing and give it the proper coordinates. Any thoughts on that maybe working?

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Xref multiple times with one dwg file
« Reply #24 on: November 22, 2011, 03:02:10 PM »
So you need to take the blocks out and change them to xref for I guess memory reasons?
 
If it is the same block but with different attribute value does it need to be a different block or xref?

TJK44

  • Guest
Re: Xref multiple times with one dwg file
« Reply #25 on: November 22, 2011, 03:10:52 PM »
If it has a different attribute (partnumber) it is fine, the problem comes in when there are multiples of the same part(block). In this case each block will be a part in the drawing. If I use this code it will bring all the blocks in as xref's each referencing the correct drawing but their positions are way off.


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

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

Dim scale As Scale3d = blkRef.ScaleFactors
bref.Position = blkRef.Position
bref.Rotation = blkRef.Rotation
bref.ScaleFactors = scale

btrMs2.AppendEntity(bref)

blkRef is defined like this

Code: [Select]
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)
                    '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)
« Last Edit: November 22, 2011, 03:16:22 PM by TJK44 »

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Xref multiple times with one dwg file
« Reply #26 on: November 22, 2011, 03:26:58 PM »
Dim bref As New BlockReference(Point3d.Origin, xrefObjId)
 
That needs to be the position of the blockreference from original file.

TJK44

  • Guest
Re: Xref multiple times with one dwg file
« Reply #27 on: November 22, 2011, 03:50:11 PM »
That brings in all the blocks (parts) from the original drawing, but their positions in the new drawing are not correct. Here is what it looks like before and after I run the command with zoom extents.

Code: [Select]
Dim bref As New BlockReference(blkRef.Position, xrefObjId)

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Xref multiple times with one dwg file
« Reply #28 on: November 22, 2011, 03:59:04 PM »
Have not tested your code but will get a chance later.
Might have something to do with wblocking the blockreference or something is not getting translated correctly

TJK44

  • Guest
Re: Xref multiple times with one dwg file
« Reply #29 on: November 22, 2011, 04:03:13 PM »
Thanks a lot Jeff, let me know if you have any questions about getting it to run when you have the time.